Normal İfadeleri Öğrenme [kapalı]


166

Düzenli ifadeleri gerçekten anlamıyorum. Onları takip etmesi kolay bir şekilde açıklayabilir misiniz? Herhangi bir çevrimiçi araç veya kitap varsa, bunlara da bağlantı verebilir misiniz?

Yanıtlar:


789

En önemli kısım kavramlar. Yapı taşlarının nasıl çalıştığını anladıktan sonra, sözdizimindeki farklılıklar hafif lehçelerden biraz daha fazladır. Normal ifade motorunuzun sözdiziminin üstünde bulunan bir katman, kullandığınız programlama dilinin sözdizimidir. Perl gibi diller bu komplikasyonun çoğunu ortadan kaldırır, ancak bir C programında düzenli ifadeler kullanıyorsanız diğer hususları aklınızda bulundurmanız gerekir.

Düzenli ifadeleri istediğiniz gibi karıştırabileceğiniz ve eşleştirebileceğiniz yapı taşları olarak düşünürseniz, kendi kalıplarınızı nasıl yazacağınızı ve hata ayıklayacağınızı, aynı zamanda başkaları tarafından yazılan kalıpları nasıl anlayacağınızı öğrenmenize yardımcı olur.

Basit başlayın

Kavramsal olarak, en basit düzenli ifadeler gerçek karakterlerdir. Desen N'N' karakteriyle eşleşir.

Yan yana düzenli ifadeler dizileri eşleştirir. Örneğin, desen Nick'N', ardından 'i', ardından 'c' ve 'k' ile eşleşir.

grepUnix'te daha önce kullandıysanız - yalnızca sıradan görünümlü dizeler aramak için bile - zaten düzenli ifadeler kullanıyorsunuz! ( reİçinde grepdüzenli ifadeler ifade eder.)

Menüden sipariş

Sadece biraz karmaşıklık ekleyerek, 'Nick' veya 'nick' i desenle eşleştirebilirsiniz [Nn]ick. Köşeli parantez içindeki parça bir karakter sınıfıdır , yani ekteki karakterlerle tam olarak eşleşir. Aralıkları karakter sınıflarında da kullanabilirsiniz, bu nedenle [a-c]'a' veya 'b' veya 'c' ile eşleşir.

Desen .özeldir: yalnızca değişmez bir noktayı eşleştirmek yerine herhangi bir karakterle eşleşir . Kavramsal olarak gerçekten büyük karakter sınıfı ile aynı [-.?+%$A-Za-z0-9...].

Karakter sınıflarını menüler olarak düşünün: sadece birini seçin.

Yardımcı kısayollar

Kullanmak .size çok fazla yazım kazandırabilir ve yaygın desenler için başka kısayollar da vardır. Bir rakamla eşleşmek istediğinizi varsayalım: bu yazmanın bir yolu [0-9]. Rakamlar sıkça eşlenen bir hedeftir, bunun yerine kısayolu kullanabilirsiniz \d. Diğerleri \s(boşluk) ve \w(kelime karakterleri: alfasayısal veya alt çizgi).

Büyük harfli varyantlar tamamlayıcılarıdır, bu nedenle örneğin boşluk olmayan\S herhangi bir karakterle eşleşir .

Bir kez yeterli değil

Oradan, deseninizin parçalarını niceleyicilerle tekrarlayabilirsiniz . Örneğin, desen ab?c'abc' veya 'ac' ile eşleşir çünkü ?nicelleştirici alt şablonu isteğe bağlı olarak değiştirir. Diğer niceleyiciler

  • * (sıfır veya daha fazla kez)
  • + (bir veya daha fazla kez)
  • {n}(tam olarak n kez)
  • {n,}(en az n kez)
  • {n,m}(en az n kez ancak m'den fazla değil )

Bu bloklardan bazılarını bir araya getiren model [Nn]*ick,

  • Tran
  • Nick
  • Nick
  • Nnick
  • nNick
  • nnick
  • (ve bunun gibi)

İlk maç önemli bir ders gösteriyor: *her zaman başarılı! Herhangi bir desen sıfır kez eşleşebilir.

Diğer birkaç faydalı örnek:

  • [0-9]+(ve eşdeğeri \d+), negatif olmayan tüm tamsayılarla eşleşir
  • \d{4}-\d{2}-\d{2} 2019-01-01 gibi biçimlendirilmiş tarihleri ​​eşleştirir

gruplandırma

Bir niceleyici deseni hemen soluna değiştirir. 0abc+0'0abc0', '0abcabc0' ve benzerlerini eşleştirmeyi bekleyebilirsiniz , ancak artı nicelleştiricinin hemen solundaki desen c. Bu, 0abc+0'0abc0', '0abcc0', '0abccc0' vb. İle eşleştiği anlamına gelir .

Bir veya daha fazla 'abc' dizisini uçlardaki sıfırlarla eşleştirmek için kullanın 0(abc)+0. Parantezler, birim olarak ölçülebilen bir alt deseni belirtir. Normal ifade motorlarının, giriş metninin parantez içindeki bir grupla eşleşen kısmını kaydetmesi veya "yakalaması" da yaygındır. Bu şekilde bit ayıklama, endeksleri saymaktan çok daha esnek ve daha az hataya açıktır ve substr.

nöbetleşme

Daha önce, 'Nick' veya 'nick' ile eşleşmenin bir yolunu gördük. Diğeri ise olduğu gibi değişimle Nick|nick. Değişimin solundaki her şeyi ve sağındaki her şeyi içerdiğini unutmayın. Kapsamını sınırlamak için parantez gruplama kullanın |, örneğin , (Nick|nick).

Başka bir örnek [a-c]olarak a|b|c, eşzamanlı olarak şöyle yazabilirsiniz , ancak birçok uygulama alternatifin 1'den büyük uzunluklara sahip olacağını varsayacağından, bu muhtemelen yetersizdir.

kaçan

Bazı karakterler kendileriyle eşleşse de, diğerleri özel anlamlara sahiptir. Desen \d+ters eğik çizgi, ardından küçük D harfi ve artı işaretiyle eşleşmez: Bunu elde etmek için kullanırız \\d\+. Ters eğik çizgi, aşağıdaki karakterden özel anlamı kaldırır.

açgözlülük

Normal ifade nicelikleri açgözlüdür. Bu, tüm desenin başarılı bir şekilde eşleşmesine izin verirken mümkün olduğunca çok metin eşleştirdikleri anlamına gelir.

Örneğin, girdinin

"Merhaba," dedi, "Nasılsın?"

".+"Sadece 'Merhaba' ile eşleşmeyi bekleyebilirsiniz ve daha sonra 'Merhaba' ile eşleştiğini gördüğünüzde şaşıracaksınız.

Açgözlüden temkinli olarak düşünebileceğinize ?geçmek için nicelleştiriciye bir ekstra ekleyin . Şimdi \((.+?)\)sorunun nasıl çalıştığını anlıyorsunuz . Değişmez sol parantez dizisiyle eşleşir, bunu bir veya daha fazla karakter izler ve sağ parantezle sonlandırılır.

Girişiniz '(123) (456)' ise, ilk yakalama '123' olacaktır. Açgözlü olmayan niceleyiciler, desenin geri kalanının mümkün olan en kısa sürede eşleşmeye başlamasına izin vermek ister.

(Karışıklığınıza gelince ((.+?)), aynı şeyi nerede yapacak bir düzenli ifade lehçesi bilmiyorum. Yolda bir yerde iletimde bir şeyin kaybolduğundan şüpheleniyorum.)

Çapalar

^Yalnızca girişinizin başlangıcında ve yalnızca sonunda eşleştirmek için özel deseni kullanın $. "Önde ve arkada ne olduğunu biliyorum, ama bana her şeyi ver" dediğin desenlerle "kitap ayracı" yapmak faydalı bir tekniktir.

Formun yorumlarını eşleştirmek istediğinizi varsayalım

-- This is a comment --

sen yazardın ^--\s+(.+)\s+--$.

Kendiniz oluşturun

Düzenli ifadeler özyinelemelidir, bu yüzden bu temel kuralları anladığınıza göre, bunları istediğiniz gibi birleştirebilirsiniz.

Normal ifadeleri yazma ve hata ayıklama araçları:

Kitabın

Ücretsiz kaynaklar

Dipnot

†: Yukarıdaki .herhangi bir karakterle eşleşen ifade, kesinlikle doğru olmayan pedagojik amaçlar için basitleştirmedir. Nokta, yeni satır dışındaki herhangi bir karakterle eşleşir "\n", ancak pratikte .+, yeni satır sınırını aşmak gibi nadiren bir desen beklersiniz . Perl regex'leri , örneğin herhangi bir karakterle eşleştirmek için bir /sanahtara ve Java'ya sahiptir . Böyle bir özelliği olmayan diller için, "herhangi bir boşluk veya herhangi bir boşluk olmayan", diğer bir deyişle herhangi bir şeyle eşleşmek gibi bir şey kullanabilirsiniz.Pattern.DOTALL.[\s\S]


14
Ayrıca deneme yanılma yöntemini kullanabilirsiniz ve çevrimiçi regex tester ve hata ayıklayıcı takip daha büyük bir yardımcı olabilir: regex101.com
Juraj.Lorinc

2
Benzer bir desen olmasına rağmen a{,m}, en azından Javascript, Perl ve Python'da bir şey olmadığını belirtmek gerekir .
Monica'nın Davası

2
Hepsinin farklı özellik setlerine ve sözdizimsel kurallara sahip farklı türden düzenli ifade motorları olduğunu belirtmek gerekir.
hek2mgl

1
hackr.io/tutorials/learn-regular-expressions-regex en iyi çevrimiçi normal ifade eğitimlerini bulmak için harika bir yerdir. Buradaki tüm öğreticiler programlama topluluğu tarafından gönderilir ve önerilir (SO gibi yükseltilir).
Saurabh Hooda

2
Hepsini buraya getirmek için gösterdiğiniz çaba için teşekkür ederiz.
Saurabh Tiwari
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.