Question Expression régulière, diviser la chaîne par lettre majuscule mais ignorer TLA


J'utilise la regex

System.Text.RegularExpressions.Regex.Replace(stringToSplit, "([A-Z])", " $1").Trim()

diviser les chaînes par lettre majuscule, par exemple:

'MyNameIsSimon' devient «Mon nom est Simon»

Je trouve cela incroyablement utile lorsque vous travaillez avec des énumérations. Ce que je voudrais faire, c’est le changer légèrement pour que les chaînes ne soient divisées que si le prochain lettre est une lettre minuscule, par exemple:

'USA aujourd'hui' deviendrait 'USA aujourd'hui'

Est-ce que cela peut être fait?

EDIT: Merci à tous pour votre réponse. Je n'ai peut-être pas complètement réfléchi à cela, dans certains cas, «A» et «I» devraient être ignorés, mais ce n'est pas possible (du moins pas de manière significative). Dans mon cas, les réponses ci-dessous font ce que j'ai besoin. Merci!


25
2017-07-08 12:58


origine


Réponses:


((? <= [a-z]) [A-Z] | [A-Z] (? = [a-z]))

ou son cousin Unicode-conscient

((? <= \ p {Ll}) \ p {Lu} | \ p {Lu} (? = \ p {Ll}))

lorsqu'il est remplacé globalement avec

" $1"

poignées

TodayILiveInTheUSAWithSimon
USA aujourd'hui
IAmSOOOBored

céder

 Aujourd'hui je vis aux USA avec Simon
USA aujourd'hui
Je suis SOOO Bored

Dans un deuxième temps, vous devrez couper la chaîne.


40
2017-07-08 13:21



tout caractère majuscule non suivi d'une majuscule:

Replace(string, "([A-Z])(?![A-Z])", " $1")

Modifier:

Je viens de remarquer que vous l'utilisez pour des énumérations. Je n'encourage vraiment pas l'utilisation de représentations en chaîne des énumérations comme celle-ci, et les problèmes à résoudre sont une bonne raison. Regardez plutôt ceci: http://www.refactoring.com/catalog/replaceTypeCodeWithClass.html


11
2017-07-08 13:00



Vous pourriez penser à changer les énumérations; Les directives de codage MS suggèrent que les acronymes de casing Pascal sont des mots; XmlDocument, HtmlWriter, etc. Les acryonymes à deux lettres ne suivent pas cette règle, cependant; System.IO.

Donc, vous devriez utiliser UsaToday, et votre problème disparaîtra.


1
2017-07-08 13:03



J'espère que cela vous aidera à diviser une chaîne par ses majuscules et bien plus encore. Vous pouvez essayer d'utiliser Humanizer, qui est un paquet nuget gratuit. Cela vous évitera plus de problèmes avec les lettres, les phrases, les nombres, les quantités et bien plus encore dans de nombreuses langues. Découvrez ceci à: https://www.nuget.org/packages/Humanizer/ 


1
2018-01-12 19:08



L’expression de Tomalak a fonctionné pour moi, mais pas avec le Replace fonction. Regex.Replace(), cependant, a travaillé.

For i As Integer = 0 To names.Length - 1
  'Worked
  names(i) = Regex.Replace(names(i), "((?<=[a-z])[A-Z]|[A-Z](?=[a-z]))", " $1").TrimStart()

  ' Didn't work
  'names(i) = Replace(names(i), "([A-Z])(?=[a-z])|(?<=[a-z])([A-Z])", " $1").TrimStart()
Next

BTW, j'utilise cela pour diviser les mots en noms d'énumération pour l'affichage dans l'interface utilisateur et cela fonctionne parfaitement.


0
2017-12-19 00:34



Note: Je n'ai pas lu la question assez bien, USAToday retournera "Today"; donc cette réponse n'est pas la bonne.

    public static List<string> SplitOnCamelCase(string text)
    {
        List<string> list = new List<string> ();
        Regex regex = new Regex(@"(\p{Lu}\p{Ll}+)");
        foreach (Match match in regex.Matches(text))
        {
            list.Add (match.Value);
        }
        return list;
    }

Cela correspondra à "WakeOnBoot" en tant que "Wake On Boot" et ne renverra rien sur NMI ou TLA


0
2018-04-19 13:08



Ma version qui gère également des expressions arithmétiques simples:

private string InjectSpaces(string s)
{
    var patterns = new string[] {
        @"(?<=[^A-Z,&])[A-Z]",          // match capital preceded by any non-capital except ampersand
        @"(?<=[A-Z])[A-Z](?=[a-z])",    // match capital preceded by capital and followed by lowercase letter
        @"[\+\-\*\/\=]",                // match arithmetic operators
        @"(?<=[\+\-\*\/\=])[0-9,\(]"    // match 0-9 or open paren preceded by arithmetic operator
    };
    var pattern = $"({string.Join("|", patterns)})";
    return Regex.Replace(s, pattern, " $1");
}

0
2017-08-08 14:51