Bienvenue à Unicode
Toutes ces solutions sont essentiellement erronées pour les textes modernes. Vous devez utiliser quelque chose qui comprend la casse. Puisque Bob a demandé d'autres langages, je vais en donner quelques-uns pour Perl.
Je propose quatre solutions, de la pire à la meilleure. Seule la meilleure est toujours la bonne. Les autres ont des problèmes. Voici un essai pour vous montrer ce qui fonctionne et ce qui ne fonctionne pas, et où. J'ai utilisé des traits de soulignement pour que vous puissiez voir où les espaces ont été mis, et j'ai marqué comme faux tout ce qui est, eh bien, faux.
Testing TheLoneRanger
Worst: The_Lone_Ranger
Ok: The_Lone_Ranger
Better: The_Lone_Ranger
Best: The_Lone_Ranger
Testing MountMKinleyNationalPark
[WRONG] Worst: Mount_MKinley_National_Park
[WRONG] Ok: Mount_MKinley_National_Park
[WRONG] Better: Mount_MKinley_National_Park
Best: Mount_M_Kinley_National_Park
Testing ElÁlamoTejano
[WRONG] Worst: ElÁlamo_Tejano
Ok: El_Álamo_Tejano
Better: El_Álamo_Tejano
Best: El_Álamo_Tejano
Testing TheÆvarArnfjörðBjarmason
[WRONG] Worst: TheÆvar_ArnfjörðBjarmason
Ok: The_Ævar_Arnfjörð_Bjarmason
Better: The_Ævar_Arnfjörð_Bjarmason
Best: The_Ævar_Arnfjörð_Bjarmason
Testing IlCaffèMacchiato
[WRONG] Worst: Il_CaffèMacchiato
Ok: Il_Caffè_Macchiato
Better: Il_Caffè_Macchiato
Best: Il_Caffè_Macchiato
Testing Misterenanubovi
[WRONG] Worst: Misterenanubovi
[WRONG] Ok: Misterenanubovi
Better: Mister_enan_ubovi
Best: Mister_enan_ubovi
Testing OleKingHenry
[WRONG] Worst: Ole_King_Henry
[WRONG] Ok: Ole_King_Henry
[WRONG] Better: Ole_King_Henry
Best: Ole_King_Henry_
Testing CarlosºElEmperador
[WRONG] Worst: CarlosºEl_Emperador
[WRONG] Ok: Carlosº_El_Emperador
[WRONG] Better: Carlosº_El_Emperador
Best: Carlos_º_El_Emperador
D'ailleurs, presque tout le monde ici a choisi la première méthode, celle qui est marquée "Pire". Quelques-uns ont choisi la deuxième méthode, marquée "OK". Mais personne avant moi ne vous a montré comment faire la "meilleure" ou la "meilleure" approche.
Voici le programme de test avec ses quatre méthodes :
#!/usr/bin/env perl
use utf8;
use strict;
use warnings;
# First I'll prove these are fine variable names:
my (
$TheLoneRanger ,
$MountMKinleyNationalPark ,
$ElÁlamoTejano ,
$TheÆvarArnfjörðBjarmason ,
$IlCaffèMacchiato ,
$Misterenanubovi ,
$OleKingHenry ,
$CarlosºElEmperador ,
);
# Now I'll load up some string with those values in them:
my @strings = qw{
TheLoneRanger
MountMKinleyNationalPark
ElÁlamoTejano
TheÆvarArnfjörðBjarmason
IlCaffèMacchiato
Misterenanubovi
OleKingHenry
CarlosºElEmperador
};
my($new, $best, $ok);
my $mask = " %10s %-8s %s\n";
for my $old (@strings) {
print "Testing $old\n";
($best = $old) =~ s/(?<=\p{Lowercase})(?=[\p{Uppercase}\p{Lt}])/_/g;
($new = $old) =~ s/(?<=[a-z])(?=[A-Z])/_/g;
$ok = ($new ne $best) && "[WRONG]";
printf $mask, $ok, "Worst:", $new;
($new = $old) =~ s/(?<=\p{Ll})(?=\p{Lu})/_/g;
$ok = ($new ne $best) && "[WRONG]";
printf $mask, $ok, "Ok:", $new;
($new = $old) =~ s/(?<=\p{Ll})(?=[\p{Lu}\p{Lt}])/_/g;
$ok = ($new ne $best) && "[WRONG]";
printf $mask, $ok, "Better:", $new;
($new = $old) =~ s/(?<=\p{Lowercase})(?=[\p{Uppercase}\p{Lt}])/_/g;
$ok = ($new ne $best) && "[WRONG]";
printf $mask, $ok, "Best:", $new;
}
Lorsque vous obtiendrez le même score que le "meilleur" sur cet ensemble de données, vous saurez que vous l'avez fait correctement. Jusque là, vous ne l'avez pas fait. Personne d'autre ici n'a fait mieux que "Ok", et la plupart l'ont fait "Pire". J'attends avec impatience de voir quelqu'un poster le code correct.
Je remarque que le code de mise en évidence de StackOverflow est à nouveau misérablement stupide. Ils font tous les mêmes vieux trucs boiteux que (la plupart mais pas tous) le reste des approches pauvres mentionnées ici ont fait. N'est-il pas grand temps de mettre l'ASCII au repos ? Cela n'a plus de sens, et prétendre que c'est tout ce que vous avez est tout simplement faux. Cela donne un mauvais code.
3 votes
Avez-vous une plainte particulière concernant l'approche que vous avez adoptée ? Cela pourrait nous aider à améliorer votre méthode.
0 votes
Si la regex fonctionne, alors je m'en tiendrais à cela. La regex est optimisée pour la manipulation des chaînes de caractères.
0 votes
Je suis simplement curieux de savoir s'il existe une meilleure approche ou peut-être même une approche intégrée. Je serais même curieux de voir d'autres approches avec d'autres langages.
4 votes
Votre code n'a tout simplement pas fonctionné parce que la chaîne modifiée est la valeur de retour de la fonction 'Replace'. Avec cette ligne de code : 'System.Text.RegularExpressions.Regex.Replace(value, "[A-Z]", " $0").Trim();', cela fonctionnerait parfaitement. (Je commente juste parce que je suis tombé par hasard sur ce post et personne n'a vraiment vu, ce qui n'allait pas avec votre code).
0 votes
Regex.Replace("ThisStringHasNoSpacesButItDoesHaveCapitals", @" \B [A-Z]", m => " " + m) ;