Étant donné la chaîne "ThisStringHasNoSpacesButItDoesHaveCapitals", quelle est la meilleure façon d'ajouter des espaces avant les majuscules. Ainsi, la chaîne de fin serait "Cette chaîne n'a pas d'espaces mais elle a des majuscules"
Voici ma tentative avec un RegEx
System.Text.RegularExpressions.Regex.Replace(value, "[A-Z]", " $0")
Réponses:
Les expressions rationnelles fonctionneront bien (j'ai même voté pour la réponse de Martin Browns), mais elles sont chères (et personnellement, je trouve n'importe quel modèle plus long que quelques caractères prohibitifs)
Cette fonction
Le fera 100 000 fois en 2 968 750 ticks, le regex prendra 25 000 000 ticks (et c'est avec le regex compilé).
C'est mieux, pour une valeur donnée de meilleur (c'est-à-dire plus rapide) mais c'est plus de code à maintenir. «Mieux» est souvent un compromis d'exigences concurrentes.
J'espère que cela t'aides :)
Mettre à jour
Cela fait longtemps que je n'ai pas regardé cela, et je viens de réaliser que les timings n'ont pas été mis à jour depuis que le code a changé (il a seulement changé un peu).
Sur une chaîne avec 'Abbbbbbbbb' répété 100 fois (c.-à-d. 1 000 octets), une série de 100 000 conversions prend la fonction codée à la main 4 517 177 tics, et le Regex ci-dessous prend 59 435 719, ce qui rend la fonction codée à la main exécutée dans 7,6% du temps qu'il faut Regex.
Mise à jour 2 Tiendra-t-elle compte des acronymes? Ce sera maintenant! La logique de l'énoncé if est assez obscure, comme vous pouvez le voir élargir à cela ...
... n'aide pas du tout!
Voici la méthode simple d' origine qui ne se soucie pas des acronymes
la source
Votre solution a un problème en ce qu'elle met un espace avant la première lettre T afin que vous obteniez
Pour contourner ce problème, recherchez également la lettre minuscule qui la précède, puis insérez l'espace au milieu:
Modifier 1:
Si vous l'utilisez,
@"(\p{Ll})(\p{Lu})"
il récupérera également les caractères accentués.Modifier 2:
Si vos chaînes peuvent contenir des acronymes, vous pouvez utiliser ceci:
Ainsi, "DriveIsSCSICompatible" devient "Drive Is SCSI Compatible"
la source
"([^A-Z\\s])([A-Z])"
, même avec des acronymes?N'a pas testé les performances, mais ici en ligne avec linq:
la source
Je sais que c'est une ancienne, mais c'est une extension que j'utilise lorsque je dois le faire:
Cela vous permettra d'utiliser
MyCasedString.ToSentence()
la source
TrimStart(' ')
cela supprimera l'espace de tête.SelectMany
qui inclut un index, de cette façon, elle évite la première lettre et la surcharge potentielle inutile d'un appel supplémentaire àTrimStart(' ')
. Rob.Bienvenue chez Unicode
Toutes ces solutions sont essentiellement erronées pour le texte moderne. Vous devez utiliser quelque chose qui comprend la casse. Puisque Bob a demandé d'autres langues, je vais en donner quelques-unes pour Perl.
Je propose quatre solutions, allant du pire au meilleur. Seul le meilleur a toujours raison. Les autres ont des problèmes. Voici un test 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é placés, et j'ai marqué comme mauvais tout ce qui est, bien, mauvais.
BTW, presque tout le monde ici a choisi la première voie, celle marquée "Pire". Quelques-uns ont sélectionné la deuxième voie, marquée "OK". Mais personne d'autre avant moi ne vous a montré comment faire l'approche "meilleure" ou "meilleure".
Voici le programme de test avec ses quatre méthodes:
Lorsque vous pouvez obtenir 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'ai hâte de voir quelqu'un poster le bon code ℂ♯.
Je remarque que le code de surbrillance de StackOverflow est à nouveau misérablement stupide. Ils font tout de même le même vieux boiteux que (la plupart mais pas tous) du reste des mauvaises approches mentionnées ici. N'est-il pas grand temps de mettre 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 fait un mauvais code.
la source
J'ai décidé de créer une méthode d'extension simple basée sur le code de Binary Worrier qui gérera correctement les acronymes et est reproductible (ne modifie pas les mots déjà espacés). Voici mon résultat.
Voici les cas de tests unitaires que cette fonction réussit. J'ai ajouté la plupart des cas suggérés par tchrist à cette liste. Les trois de ceux qu'il ne réussit pas (deux ne sont que des chiffres romains) sont commentés:
la source
Binary Worrier, j'ai utilisé votre code suggéré, et il est plutôt bon, je n'ai qu'un ajout mineur:
J'ai ajouté une condition
!char.IsUpper(text[i - 1])
. Cela a corrigé un bug qui faisait que quelque chose comme «AverageNOX» était transformé en «Average NO X», ce qui est évidemment faux, car il devrait se lire «Average NOX».Malheureusement, cela a toujours le bug que si vous avez le texte «FromAStart», vous obtiendrez «From AStart».
Des réflexions sur la résolution de ce problème?
la source
if (char.IsUpper(text[i]) && !(char.IsUpper(text[i - 1]) && char.IsUpper(text[i + 1])))
Résultat du test: "From Start", "From THE Start", "From A Start" mais vous avez besoini < text.Length - 1
dans la condition de boucle for d'ignorer le dernier caractère et d'éviter les exceptions hors limites.Voici la mienne:
la source
<pre><code>code</code></pre>
bloc au lieu de la syntaxe Markdown. Pas besoin de le contrer (si c'était vous).Assurez-vous que vous ne placez pas d' espaces au début de la chaîne, mais que vous les placez entre des majuscules consécutives. Certaines des réponses ici n'abordent pas l'un ou les deux de ces points. Il existe d'autres façons que l'expression régulière, mais si vous préférez l'utiliser, essayez ceci:
Le
\B
est un nié\b
, il représente donc une frontière non mot. Cela signifie que le motif correspond à "Y" dansXYzabc
, mais pas dansYzabc
ouX Yzabc
. En bonus, vous pouvez l'utiliser sur une chaîne avec des espaces et cela ne les doublera pas.la source
Cette expression régulière place un caractère espace devant chaque lettre majuscule:
Attention à l'espace devant si "$ 1 $ 2", c'est ce qui le fera.
Voici le résultat:
la source
"([A-Z0-9])([a-z]*)"
Ce que vous avez fonctionne parfaitement. N'oubliez pas de réaffecter
value
à la valeur de retour de cette fonction.la source
Voici comment vous pouvez le faire en SQL
la source
Inspiré de @MartinBrown, Two Lines of Simple Regex, qui résoudra votre nom, y compris les acyronymes n'importe où dans la chaîne.
la source
la source
la source
En Ruby, via Regexp:
la source
J'ai pris l'excellente solution de Kevin Strikers et je me suis converti en VB. Étant donné que je suis verrouillé dans .NET 3.5, j'ai également dû écrire IsNullOrWhiteSpace. Cela passe tous ses tests.
la source
La question est un peu ancienne mais de nos jours il existe une belle bibliothèque sur Nuget qui fait exactement cela ainsi que de nombreuses autres conversions en texte lisible par l'homme.
Découvrez Humanizer sur GitHub ou Nuget.
Exemple
la source
Semble être une bonne occasion pour
Aggregate
. Ceci est conçu pour être lisible, pas nécessairement particulièrement rapide.la source
En plus de la réponse de Martin Brown, j'avais également un problème avec les chiffres. Par exemple: «Location2» ou «Jan22» doit être «Location 2» et «Jan 22» respectivement.
Voici mon expression régulière pour ce faire, en utilisant la réponse de Martin Brown:
Voici quelques excellents sites pour comprendre ce que chaque partie signifie également:
Analyseur d'expressions régulières basé sur Java (mais fonctionne pour la plupart des expressions régulières .net)
Analyseur basé sur un script d'action
La regex ci-dessus ne fonctionnera pas sur le site de script d'action à moins que vous ne remplaciez tous les
\p{Ll}
avec[a-z]
, les\p{Lu}
avec[A-Z]
et\p{Nd}
avec[0-9]
.la source
Voici ma solution, basée sur la suggestion de Binary Worriers et la construction dans les commentaires de Richard Priddys, mais tenant également compte du fait que des espaces blancs peuvent exister dans la chaîne fournie, de sorte qu'il n'ajoutera pas d'espace blanc à côté des espaces blancs existants.
la source
Pour tous ceux qui recherchent une fonction C ++ répondant à cette même question, vous pouvez utiliser ce qui suit. Ceci est modélisé d'après la réponse donnée par @Binary Worrier. Cette méthode conserve simplement les acronymes automatiquement.
Les chaînes de test que j'ai utilisées pour cette fonction, et les résultats sont les suivants:
la source
Une solution C # pour une chaîne d'entrée composée uniquement de caractères ASCII. La regex incorpore un lookbehind négatif pour ignorer une lettre majuscule (majuscule) qui apparaît au début de la chaîne. Utilise Regex.Replace () pour renvoyer la chaîne souhaitée.
Voir également la démo regex101.com .
Production attendue:
Mise à jour: voici une variante qui traitera également les acronymes (séquences de lettres majuscules).
Voir également la démo regex101.com et la démo ideone.com .
Production attendue:
la source
Voici une solution plus approfondie qui ne met pas d'espaces devant les mots:
Remarque: j'ai utilisé plusieurs expressions régulières (pas concises, mais elle traitera également les acronymes et les mots d'une seule lettre)
Dans :
Sortie :
la source
Toutes les réponses précédentes semblaient trop compliquées.
J'avais une chaîne qui avait un mélange de majuscules et de _ donc utilisé, string.Replace () pour faire le _, "" et utilisé ce qui suit pour ajouter un espace en majuscules.
la source
Inspiré par la réponse de Binary Worrier, j'ai pris un élan à cela.
Voici le résultat:
A testé en utilisant un chronomètre exécutant 10000000 itérations et différentes longueurs de chaîne et combinaisons.
En moyenne 50% (peut-être un peu plus) plus rapidement que la réponse Binary Worrier.
la source
la source
Celui-ci comprend des acronymes et des pluriels d'acronymes et est un peu plus rapide que la réponse acceptée:
Réussit ces tests:
la source
Une implémentation avec
fold
, également connue sous le nom deAggregate
:En plus de la demande, cette implémentation enregistre correctement les espaces et acronymes de début, intérieurs et finaux, par exemple,
la source
Un moyen simple d'ajouter des espaces après les minuscules, les majuscules ou les chiffres.
la source