"Hiçbir şeyle eşleşmiyor" için normal ifade sözdizimi?


83

Yoğun şekilde regexp kullanan bir python şablon motorum var. Aşağıdaki gibi birleştirme kullanır:

re.compile( regexp1 + "|" + regexp2 + "*|" + regexp3 + "+" )

Tek tek alt dizeleri değiştirebilirim (regexp1, regexp2 vb.).

Eşleşme istemediğim bir şablonda kullanabileceğim, hiçbir şeyle eşleşmeyen küçük ve hafif bir ifade var mı? Ne yazık ki, bazen regexp atomuna '+' veya '*' eklenir, bu nedenle boş bir dize kullanamam - bu "tekrarlanacak bir şey yok" hatası verir.



3
Başlık, "Hiçbir şeyle eşleşemeyen normal ifade" olarak daha iyi ifade edilebilir mi? Hiçbir şeyin eşleşmemesi, boş bir dizenin başarılı bir şekilde eşleştiği anlamına gelir.
BamaPookie

Yanıtlar:


126

Bu hiçbir şeyle eşleşmemelidir:

re.compile('$^')

Dolayısıyla, regexp1, regexp2 ve regexp3'ü '$ ^' ile değiştirirseniz eşleşme bulmak imkansız olacaktır. Çoklu hat modunu kullanmadığınız sürece.


Bazı testlerden sonra daha iyi bir çözüm buldum

re.compile('a^')

Eşleşmesi imkansızdır ve önceki çözümden daha erken başarısız olacaktır. A'yı başka herhangi bir karakterle değiştirebilirsiniz ve eşleştirmek her zaman imkansız olacaktır.


Bu kesinlikle hiçbir şeyle eşleşmeyecek ve regexp motorunun işlemesi için hafif mi? (saplama
regexps'imin

@ Cehennem gözü. Hafif olmalıdır. Bu, bir satır sonu ve ardından bir satır başlangıcı ile eşleşmeye çalışacaktır. Tek satırda imkansız olan.
Nadia Alramli

1
Ancak elbette birden fazla satırla mümkündür (bayrağın etkinleştirilip etkinleştirilmediğine bağlı olarak) - bayrağın etkin olup olmamasına bağlı olarak çalışan bir çözüm için cevabıma bakın.
Peter Boughton

16
"$ ^" Normal ifadesi, en azından bazı uygulamalarda boş dizeyle eşleşir. İkincisi daha iyi.
Roman Starkov

@romkyns İkincisi, PyQt4'e yaptığım çağrımda boş dizeyle eşleşmiyor QtCore.QRegExp. O kadar kötü ki, uygulanması kesinlikle daha hafif olurdu.
Joël

44

(?!)her zaman eşleşmede başarısız olmalıdır. Sıfır genişlikli negatif önden bakmadır. Parantez içindekiler eşleşirse, tüm eşleşme başarısız olur. İçinde hiçbir şey olmadığı göz önüne alındığında, maçta herhangi bir şey için başarısız olur (hiçbir şey dahil).


4
Doğru, ben de bunu gönderecektim. Diliniz ileri görüşleri destekliyorsa bu en iyi yoldur. Aynı şekilde (? =) Her dizeyle eşleşir.
Brian Carper

16

Boş bir dizeyi eşleştirmek için - çok satırlı modda bile - kullanabilirsiniz \A\Z, böylece:

re.compile('\A\Z|\A\Z*|\A\Z+')

Fark olduğunu \Ave \Zbaşlangıç ve bitiş edilir dize iken, ^ve $bu başlangıç / sonunu eşleşebilir hatları , böylece $^|$^*|$^+potansiyel olarak (bayrak etkinse) yeni satır içeren bir dize maç olabilir.

Ve herhangi bir şeyi (boş bir dizeyi bile) eşleştirememek için, dizenin başlangıcından önce içeriği bulmaya çalışın, örneğin:

re.compile('.\A|.\A*|.\A+')

Hiçbir karakter \ A'dan (tanım gereği) önce gelemeyeceğinden, bu her zaman eşleşmeyecektir.


Seninki benimkinden daha güzel görünüyor, çünkü satır sonunu kullanmaktan daha hızlı çıkacağını varsayıyorum.
ShuggyCoUk

Peter, Python cep rehberim bana dizge sonu iddiasının \ Z (büyük harf) olduğunu söylerken \ z (küçük harf) kullanıyorsun ?!
ThomasH

ThomasH, ikisi de dizgenin sonudur, ancak büyük harfli sürüm son satır satırına izin verirken, küçük harf yapmaz.
Peter Boughton

Mh, ilginç, bunu hiçbir yerde belgelenmemiş buluyorum. Ayrıca, re.search ("boo \ z", "fooboo") bir eşleşme nesnesi döndürmezken, re.search ("boo \ Z", "fooboo) döndürür . Bunun yerine, re.search (" boo \ z "," foobooz ") eşleşir, '\ z' basitçe 'z' olarak yorumlanır, değil mi ?! (Bu Python 2.6'da).
ThomasH

Ah üzgünüm, Python'un PCRE olduğunu düşünmüştüm, ancak birkaç farklılık olduğu ortaya çıktı ve bu onlardan biri. ( Regular-expressions.info/refflavors.html adresinde 'Çapalar' bölümüne bakın )
Peter Boughton


1

Kullanabilirsiniz
\z..
Bu, dizenin mutlak sonudur, ardından iki şey gelir

Eğer +veya *sonuna tacked bu hala bir şey eşleştirmek reddederek işleri


Neden iki şey? IIRC \z, aksine \Z, satırsonu satırlarına izin vermez , bu yüzden yeterli olmaz mı? Ya da bu garip bir savunma *(neden buna karşı
korunuyorsunuz

0

Veya, gereksiz normal ifade girişlerini kaldırmak için bir liste anlama kullanın ve hepsini bir araya getirmek için birleştirin. Gibi bir şey:

re.compile('|'.join([x for x in [regexp1, regexp2, ...] if x != None]))

Yine de bu kod satırının yanına bazı yorumlar eklediğinizden emin olun :-)

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.