Regex - belirli bir model dışındaki her şey nasıl eşleştirilir


Yanıtlar:


192

İleriye dönük bir iddia kullanabilirsiniz:

(?!999)\d{3}

Bu örnek, dışında üç rakamla eşleşir 999.


Ancak bu özellik ile düzenli bir ifade uygulamanız yoksa (bkz . Düzenli İfade Lezzetlerinin Karşılaştırılması ), muhtemelen temel özelliklerle kendi başınıza düzenli bir ifade oluşturmanız gerekir.

Yalnızca temel sözdizimi içeren uyumlu bir normal ifade şöyle olur:

[0-8]\d\d|\d[0-8]\d|\d\d[0-8]

Bu, aynı olmayan üç basamak dizisiyle de eşleşir 999.


1
İleriye dönük standart normal ifade sözdizimi değil, bir Perl uzantısıdır, yalnızca Perl, PCRE (Perl Uyumlu RegEx) veya diğer standart dışı uygulamalarda çalışır
Juliano

10
Standart olmayabilir, ancak çoğu modern dil bunu desteklemiyor mu? Hangi dili gelmez bu gün göz-aheads destekliyor?
Bryan Oakley

1
Bu doğru. Ancak çoğu normal ifade aroması bu özelliği destekler (bkz. < Regular-expressions.info/refflavors.html> ).
Gumbo

1
Bence son normal ifade de 009, 019 ... vs maç olmaz
Sebastian Viereck

1
Standart Lex for C PCRE kullanmaz :-(
pieman72

30

Bir dizede A kelimesini eşleştirmek ve B kelimesiyle eşleşmesini istemiyorsanız Örneğin: Bir metniniz varsa:

1. I have a two pets - dog and a cat
2. I have a pet - dog

Bir evcil hayvan için bir köpeği olan ve kedi olmayan bir metin satırı aramak istiyorsanız, bu normal ifadeyi kullanabilirsiniz:

^(?=.*?\bdog\b)((?!cat).)*$

Sadece ikinci satırı bulacaktır:

2. I have a pet - dog

O soruda söz başarısız, ama OP aslında DOS findstrkomutunu kullanıyor . Bir normal ifade aracında bulmayı beklediğiniz yeteneklerin yalnızca küçük bir alt kümesini sağlar; ileriye bakmak onların arasında değil. (Sadece findstr etiketini kendim ekledim .)
Alan Moore

2
hm, evet, şimdi gönderilerdeki yorumlarından birinde buldum. Başlıkta Regex'i gördüm. Her neyse, biri benim gibi normal ifade için aynı ararken bu yazı bulursa, belki birine yararlı olabilir :) yorumlar için teşekkürler
Aleks

15

Kalıpla eşleştirin ve maçın mantıksal sonucunu tersine çevirmek için ana bilgisayar dilini kullanın. Bu çok daha okunaklı ve bakımı kolay olacaktır.


1
Sonra sadece (A ve ~ B) yerine (~ A veya B) ile bitiriyorum. Sorunumu çözmedi.
21'de değil

1
Sözde kod: String toTest; eğer (toTest.matches (A) AND! toTest.matches (B)) {...}
Ben S

Daha açık olmalıydım - parçalar tamamen bağımsız değil. A, dizenin bir parçasıyla eşleşiyorsa, ~ B'nin geri kalanıyla eşleşip eşleşmediğini (ancak her şeyle değil) umursuyoruz. Bu buldum windows komut satırı findstr işlevi, gerçek regexs ile sınırlı olduğunu, bu yüzden moot noktası.
22.07'de

8

not değil, bu antik sorunun dirilişi, çünkü bahsedilmeyen basit bir çözümü vardı. ( Normal ifade ödül arayışı için biraz araştırma yaparken sorunuzu buldunuz .)

Bir (A ve ~ B) düzeniyle eşleşmem gereken bir durumla karşı karşıyayım.

Bunun için temel regex korkutucu derecede basittir: B|(A)

Genel maçları görmezden gelir ve A içerecek olan Grup 1 yakalamalarını incelersiniz.

Bir örnek (regex'te html'yi ayrıştırmayla ilgili tüm feragatnamelerle): A rakamdır, B içindeki rakamlardır <a tag

Normal ifade: <a.*?<\/a>|(\d+)

Demo (sağ alt bölmedeki Grup 1'e bakın)

Referans

S1, s2, s3 durumları haricinde desen nasıl eşleştirilir

Bir desen nasıl eşleşmezse ...


Bu gerçek olamayacak kadar iyi geliyor! Ne yazık ki, bu çözüm evrensel değildir ve hatta değiştirdikten sonra, Emacs başarısız \dolan [[:digit:]]. İlk referans Perl ve PHP'ye özgü olduğunu belirtiyor: "Perl ve PHP'ye özgü sözdizimini kullanan ve bunu gerçekleştiren bir varyasyon var."
miguelmorin

4

Normal bir dilin tamamlayıcısı da normal bir dildir, ancak onu oluşturmak için normal dil için DFA'yı oluşturmanız ve herhangi bir geçerli durum hatasını bir hataya dönüştürmeniz gerekir. Bkz bu bir örnek. Hangi sayfa demiyor o dönüştürülen olmasıdır /(ac|bd)/içine /(a[^c]?|b[^d]?|[^ab])/. Bir DFA'dan normal bir ifadeye dönüşme önemsiz değildir. Normal ifadeyi değişmeden kullanabilmeniz ve daha önce önerildiği gibi koddaki anlambilimi değiştirebilmeniz daha kolaydır.


2
Eğer gerçek regex ile uğraşmak olsaydı, o zaman bu tüm tartışmalı olurdu. Regex artık çoğu dilin desteklediği belirsiz CSG-ish (?) Örüntü uzayına atıfta bulunuyor gibi görünüyor. Eşleşmem gerektiğinden (A ve ~ B), olumsuzluğu kaldırmanın ve yine de tek bir adımda yapmanın bir yolu yoktur.
21

Lookahead, yukarıda açıklandığı gibi, findstr gerçek DFA normal ifadelerinin ötesinde bir şey yapsaydı bunu yapardı. Her şey biraz garip ve neden bu komut satırı (şimdi toplu iş) stilini yapmak zorunda bilmiyorum. Ellerimin bağlı olmasının başka bir örneği.
21.03'te

1
@notnot: Windows'ta findstr kullanıyor musunuz? O zaman / v. Beğen: findstr A inputfile | findstr / v B> outputfile.txt Birincisi A ile tüm satırları, ikincisi B içermeyen tüm satırları eşleştirir.
Juliano

Teşekkürler! Aslında tam da buna ihtiyacım vardı. Soruyu bu şekilde sormadım, bu yüzden daha genel cevap için hala Gumbo'ya cevap veriyorum.
Mart'ta

1

desen - yeniden

str.split(/re/g) 

desen dışında her şeyi döndürür.

Burada test edin


Muhtemelen o zaman tekrar katılmanız gerektiğini belirtmek istersiniz.
tomdemuyt

Benzer bir yaklaşım kullanıyor replace str.replace(/re/g, ''), o zaman onlara tekrar katılmaya gerek yok. ayrıca güzel bir sondaki \ s atmak eğer? o str.replace(/\re\s?/g, '')zamanki gibi , bir ipin ortasında değiştirilen bir şeyden alacağınız yinelenen boşluklardan kurtulursunuz
jakecraige

0

Buradaki cevabım sorununuzu da çözebilir:

https://stackoverflow.com/a/27967674/543814

  • Değiştir yerine, Eşleştir'i kullanırsınız.
  • Grup yerine grup $1okursunuz $2.
  • Grup $2, kaçınılmaz olarak orada yakalama yapılmadı.

Misal:

Regex.Match("50% of 50% is 25%", "(\d+\%)|(.+?)");

İlk yakalama grubu, kaçınmak istediğiniz deseni belirtir. Son yakalama grubu diğer her şeyi yakalar. Sadece bu grubu oku $2,.


0
(B)|(A)

o zaman grup 2'nin yakaladığı ...


O ihtiyacı yakalamak o sadece bütün oda desenleri görmezden değil hedefliyoruz değil B.
hexicle
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.