SORU
8 HAZİRAN 2013, CUMARTESİ


Düzenli ifade Dengeleme Grupları nelerdir?

Sadece çift ayraç (this question) içinde veri almak hakkında bir soru okuyordum, ve sonra birisi dengeleme grupları getirdi. Hala tam olarak ne olduklarını ve bunları kullanmak için nasıl emin değilim.

Balancing Group Definition ama açıklama takip etmesi zor okudum, ve hala bahsettiğim sorular oldukça kafam karıştı.

Birisi sadece dengeleme grupları ve yararlı olduklarını açıklayabilir mi?

CEVAP
8 HAZİRAN 2013, CUMARTESİ


Bildiğim kadarıyla, dengeleme gruplara özeldir .NET düzenli ifade lezzet.

Kenara Tekrarlanan Gruplar

Öncelikle, bunu bilmek gerekir .NET (yine bildiğim kadarıyla) tek bir yakalama grubunu (maç tamamlandıktan sonra geribaşvuruların ama değil) birden yakalar erişim sağlar sadece düzenli lezzet.

Bir örnekle göstermek için, desen düşünün

(.) 

ve diziyi 13**.

tüm diğer normal ifade tatlar, grup yakalama 1 sadece bir sonuç verecektir: d (not, tam maç elbette beklendiği gibi abcd). Bu yakalama grubunu her yeni bir önceki yakalama geçersiz kılar olmasıdır.

.Diğer taraftan NET hepsini hatırlar. Ve bir yığın yapar. Yukarıdaki sonra eşleşen düzenli ifade gibi

Match m = new Regex(@"(.) ").Match("abcd");

bulacaksınız

m.Groups[1].Captures

Dört çeker karşılık gelen CaptureCollection

0: "a"
1: "b"
2: "c"
3: "d"

numarasını nereden CaptureCollection dizine. Yani kısacası her zaman grup tekrar kullanılır, yeni bir yakalama da yığına itilir.

Eğer yakalama gruplarını adlı kullanıyoruz eğer daha ilginç oluyor. Çünkü .NET düzenli ifade gibi yazabiliriz aynı ismi tekrar kullanılmasını sağlar

(?<word>\w )\W (?<word>\w )

aynı gruba iki kelimeyi yakalamak. Yine, belirli bir ada sahip bir grup, bir yakalama karşılaştı her zaman yığının üzerine kendi itti. Bu yüzden giriş için bu normal ifadenin "foo bar" uygulama ve teftiş

m.Groups["word"].Captures

iki yakalar buluruz

0: "foo"
1: "bar"

Bu bizi bile ifade farklı bölgelerinden gelen tek bir yığın üzerine bir şeyler itmek için izin verir. Ama yine de, bu sadece .NET CaptureCollection Bu listelenen birden yakalar takip edebilme özelliği. Ama, bu bir koleksiyon olduğunu söylediyığın. Biz de yapabilirizpopbu şeyler?

Girin: Dengeleme Grupları

Elimizden çıkıyor. Eğer kullanırsak (?<-word>...), son yakalama gibi bir grup eğer bu ifadeyi ... eşleşirse word yığından attı. Eğer bundan önceki tüm ifadesi değişir

(?<word>\w )\W (?<-word>\w )

Sonra ikinci grup ilk grubun yakalama açılır ve sonunda boş bir CaptureCollection alacaksınız. Tabii ki, bu örnek oldukça işe yaramaz.

Eğer yığın boş zaten, grup başarısız (desenin ne olursa olsun). ama eksi-sözdizimi bir detay daha var: Bu davranış, yuvalama seviyeleri sayımı için baskı yapabiliriz - ve bu adı dengeleme grubundan (ve ilginç olan da orası) giriyor. Doğru programlama dilinde * sembolü dizeleri bu maç bizim. Biz her parantez yığın itin ve her parantez için bir yakalama pop. Biz bir kapanış parantezi çok fazla karşılaşırsanız, boş bir yığın pop ve desen başarısız olmasına neden dener:

^(?:[^()]|(?<Open>[(])|(?<-Open>[)]))*$

Bir tekrarı üç seçenek var. İlk alternatif bir parantez değildir her şeyi tüketir. İkinci alternatif yığını üzerine onları iterken (s ile eşleşir. Üçüncü alternatif yığından eleman (mümkünse!) haşhaş ise )s ile eşleşir.

Not:Sadece netleştirmek için, sadece eşsiz bir parantez vardır hayır bunu kontrol ediyoruz! Bu dize, hiçbir parantez içeren anlamına gelirhala sözdizimsel olarak geçerli olmadığı için maç, (parantez eşleştirmeniz gereken bazı sözdizimi). Eğer parantez içinde en az bir set sağlamak istiyorsanız, sadece ^ sonra ** 35 ilerleme hakkı ekleyin.

Bu desen mükemmel (ya da tamamen) doğru değildir.

Final: Koşullu Örüntüleri

Bir tane daha sorun var: bu yığın dizenin sonunda boş (dolayısıyla (foo(bar) geçerli olacaktır). garantilemez .Bir daha bunu burada bize yardımcı olur inşa var NET (ve diğer birçok tatlar): koşullu örüntüleri. Genel sözdizimi

(?(condition)truePattern|falsePattern)

falsePattern isteğe bağlı olduğu eğer belirtilmemiş ise yanlış bir durum her zaman yararınıza olacaktır. Durumu ya da bir desen veya bir yakalama grubunun adı. İkinci durumda buraya odaklanacağım. Eğer bir yakalama grubunun adı ise, o zaman truePattern yakalama, belirli bir grup değil, boş yığın, ve yalnızca kullanılır. Yani, bir koşullu desen gibi (?(name)yes|no) okur "name uyumlu ve çekilen bir şey (hala yığın), desen kullan yes aksi takdirde kullanım deseni no".

Desene bizim yukarıda sonunda eğer Open-yığın boş ise tüm seyri başarısız olmasına neden olan (?(Open)failPattern)gibi bir şey ekleyin. Desen koşulsuz başarısız yapmak için en basit şey (?!) (boş bir negatif ileri yönlü). Son desen var:

^(?:[^()]|(?<Open>[(])|(?<-Open>[)]))*(?(Open)(?!))$

Bu koşullu sözdizimi başına hiçbir şey dengeleme grupları ile ilgisi var ama gerekli tam kendi gücünü arttırmak için olduğunu unutmayın.

Burada, gökyüzü sınırdır. Çok karmaşık, birçok kullanımı mümkündür ve diğer ile birlikte kullanıldığında bazı ayrıntılar var .NET-Düzenli uzunluğu değişken geriye ilerleme (which I had to learn the hard way myself) gibi özellikler. Ancak her zaman ana soru: kodunuzu hala bu özellikleri kullanırken rahat mı? Gerçekten de belge gerekiyor, ve bunu çalışan herkes de bu özelliklerin farkında olduğundan emin olun. Aksi takdirde daha iyi, sadece ipi el ile karakter karakter yürüyüş ve bir tamsayı yuvalama seviyeleri sayma olabilir.

(?<A-B>...) sözdizimi Nedir? ek:

Bu bölüm için kredi Kobi için (onun cevabı daha fazla ayrıntı için aşağıya bakınız).

Şimdi tüm yukarıda, bir programlama dilinde * sembolü dize doğru olduğunu teyit edebiliriz. Aslında eğer alabilirsek ama çok daha yararlı olacaktır (iç içe geçmiş) o parantez için yakalar' içeriği. Tabii ki, açılış unutmayın ve ayrı bir çekim değil boşaltılmış bir yığın parantez kapatılıyor ve bazı dize çıkarma ayrı bir adımda konumlarına göre yapın edebiliriz.

Ama .NET bir rahatlık sağlar Daha fazla özellik burada: eğer biz kullanmak (?<A-B>subPattern), sadece bir yakalama attı yığından B, ama aynı zamanda her şey arasında o attı yakalama B ve bu mevcut grup itilmiş üzerine yığını A. Yığından bizim yuvalama seviyeleri haşhaş ise eğer kapanış parantez için böyle bir grup kullanırsak çok da üzerine başka bir çifti içerik yığını basabiliriz:

^(?:[^()]|(?<Open>[(])|(?<Content-Open>[)]))*(?(Open)(?!))$

Kobi cevabı Live-Demo bunu sağladı

Tüm bunları atıyor çok birlikte olabiliriz:

  • Keyfi olarak birçok yakalar unutmayın
  • İç içe geçmiş yapılar doğrulamak
  • Her yuvalama seviyesini yakalamak

Tek bir normal ifade. Eğer bu heyecan verici değilse... ;)

Ben onları ilk öğrendiği zaman yararlı bulduğum bazı kaynaklar:

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • kruno j

    kruno j

    6 Mayıs 2007
  • MagmaRhino

    MagmaRhino

    16 Temmuz 2011
  • Mark Halberstadt

    Mark Halbers

    19 ŞUBAT 2010