Soru Normal ifade, büyük harfle dizgeyi ayır, ancak TLA'yı yoksay


Regex kullanıyorum

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

Dizeleri büyük harfle ayırmak, örneğin:

'Benim adım Simon' olur 'Benim adım Simon'

Numaralandırmalarla çalışırken bunu inanılmaz derecede faydalı buluyorum. Yapmak istediğim şey biraz değiştirmek, böylece dizgiler sadece Sonraki mektubu küçük harftir, örneğin:

'Bugün Amerika' olacaktı 'Bugün Amerika'

Bu yapılabilir mi?

EDIT: Yanıt vermek için herkese teşekkürler. Bunu tamamen düşünmemiş olabilirim, bazı durumlarda 'A' ve 'I' göz ardı edilmeli ama bu mümkün değil (en azından anlamlı bir şekilde). Benim durumumda, aşağıdaki cevaplara ihtiyacım var. Teşekkürler!


25
2017-07-08 12:58


Menşei


Hmmm ... Bu başlangıçta düşündüğünüz kadar basit olmayabilir - "TodayILiveInTheUSAWithSimon" gibi bir dizge hakkında - her ikisi de mevcut cevaplar bunun için başarısız olacaktır. - Peter Boughton
İyi bir nokta. Bu örnekte olsa da muhtemelen etrafta çalışabilirim. - Simon


Cevaplar:


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

ya da Unicode-bilinçli kuzeni

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

global olarak değiştirildiği zaman

" $1"

kolları

TodayILiveInTheUSAWithSimon
Bugün Amerika
IAmSOOOBored

verimli

 Bugün Simon'la ABD'de Yaşıyorum
Bugün Amerika
Ben sOOO bıkkın

İkinci adımda dizgiyi kırpmanız gerekir.


40
2017-07-08 13:21



Üzgünüm, beni biraz kaybettin! Bunun gibi: (stringToSplit, "([A-Z]) (? = [A-z]) | (? <= [A-z]) ([A-Z])", "\ 1") değiştirin? - Simon
([A-Z])(?<=[a-z]\1|[A-Za-z]\1(?=[a-z])) alanı en baştan eklemez çünkü ilk harfi asla eşleştiremez. :) - Alan Moore
Dize uzantısı yöntemine dönüştürüldü: public static string SeperateCamelCase(this string value) { return Regex.Replace(value, "((?<=[a-z])[A-Z]|[A-Z](?=[a-z]))", " $1"); } - Tr1stan
Bir düzeltme ihtiyacını gidermek için şunu önerebilirim: ((? <= [A-z]) [A-Z] | (? <! ^) [A-Z] (? = [A-z])) - Phil
@AlanMoore'un yayınladığı bir unicode-bilinçli sürümü, hayır .Trim() İlk harfle eşleşmediği için çağrı gerekli: @"(\p{Lu})(?<=\p{Ll}\1|(\p{Lu}|\p{Ll})\1(?=\p{Ll}))" - johnnyRose


Büyük harfli bir karakter tarafından takip edilmeyen herhangi bir büyük harf:

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

Düzenle:

Bunu numaralandırma için kullandığınızı fark ettim. Gerçekten böyle sayımların dize ile temsil edilmesini teşvik etmiyorum ve eldeki problemler neden iyi bir sebep. Bunun yerine bir göz atın: http://www.refactoring.com/catalog/replaceTypeCodeWithClass.html


11
2017-07-08 13:00



Bu, "Ben" i, yani "IAmBored" i ele almaz, OP'nin beklediği gibi "Ben Sıkıldım" diye bölünmez. - Brian Rasmussen
Yanlış olduğunu düşünüyorum. Bu javascript'i kendiniz deneyin: alert ("IAmBored" .replace (/ ([A-Z]) (?! [A-Z]) / g, "$ 1")); Her ikisi de büyük harfli bir karakter tarafından takip edilmediği ve "A" ve "B" olarak değiştirileceği için "A" ve "B" eşleşecektir. - David Hedlund
(Sadece sizin seçtiğiniz örnekle karıştırıldığını fark ettim, ancak genel nokta, "Ben" in bir cümlenin ortasında olduğu zaman için hala doğrudur) - David Hedlund
Ayrıca "BornInTheUSA" da "A" dan önce bir boşluk ekler. - Alan Moore


Numaraları değiştirmeyi düşünebilirsiniz; MS kodlama yönergeleri, Pascal muhafaza kısaltmalarını, sanki kelimelermiş gibi gösterir; XmlDocument, HtmlWritervb. İki harfli akononyler bu kuralı takip etmez; System.IO.

Yani kullanmalısın UsaTodayve senin problemin ortadan kalkacak.


1
2017-07-08 13:03



Genel olarak tamamen seninleyken, bu problemi çözmüyor. Eğer UsaToday'ı yazmış olsaydı, bu, her zaman ABD’ye yazıldığından beri garip olan “Usa Today” olarak bölünmüş (yani, insan tarafından okunabilir) dizeyle sonuçlanacaktır. Bu nedenle, kapitalizasyonun korunma arzusunu anlayabiliyorum. Öte yandan, kullanıcılara enum isimlerini göstermek istendiyse, bir başka çözümle gitmeliyiz (EnumName_ValueName gibi dize kaynaklarına sahip olma eğilimindeyim, bu nedenle anahtar kodda kolayca oluşturulabilir, kaynak dosyasında aranabilir ve kolayca lokalize). - OregonGhost


Umarım bu, bir dizeyi büyük harfleriyle bölmek ve daha fazlası hakkında size yardımcı olacaktır. Kullanmayı deneyebilirsiniz Humanizerücretsiz bir nuget paketidir. Bu, birçok dilde harf, cümle, sayı, miktar ve çok daha fazlasıyla sizi daha fazla sorundan kurtarır. Şuna şunu göz atın: https://www.nuget.org/packages/Humanizer/ 


1
2018-01-12 19:08



yararlı, teşekkürler! - Simon


Tomalak'ın ifadesi benim için çalıştı, ama yerleşik değildi Replace işlevi. Regex.Replace()Ancak, işe yaramadı.

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, bunu UI'de görüntülemek için numaralandırma numaralarındaki kelimeleri bölmek için kullanıyorum ve güzel çalışıyor.


0
2017-12-19 00:34





Not: Soruyu yeterince iyi okumuştum, USAToday "Bugün" geri dönecek; Yani bu anwser doğru olanı değil.

    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;
    }

Bu "WakeOnBoot" ile "Boot On Wake" olarak eşleşecek ve NMI veya TLA'da hiçbir şey döndürmeyecek


0
2018-04-19 13:08





Benim de basit aritmetik ifadeleri işleyen sürümüm:

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