Verilen sonekle bitmeyen dize için normal ifade


190

Ben herhangi bir dize maç için uygun bir regex bulmak mümkün olmamıştır değil bazı koşulu ile biten. Örneğin, ile biten hiçbir şeyi eşleştirmek istemiyorum a.

Bu eşleşiyor

b
ab
1

Bu uyuşmuyor

a
ba

Regex'in sonu $işaretlemek için bitmesi gerektiğini biliyorum, ancak neyin önüne geçmesi gerektiğini bilmiyorum.

Edit : Orijinal soru benim durumum için yasal bir örnek gibi görünmüyor. Peki: birden fazla karakter nasıl ele alınır? Bitmeyen bir şey söyle ab?

Bu konuyu kullanarak bunu düzeltmeyi başardım :

.*(?:(?!ab).).$

Bunun dezavantajı olsa da, bir karakter dizesiyle eşleşmiyor.


5
Bu, bağlantılı sorunun bir kopyası değildir - yalnızca sonuna kadar eşleme, bir dizenin herhangi bir yerinde eşleşmekten farklı bir sözdizimi gerektirir. Buradaki en iyi cevaba bakın.
jaustin

Katılıyorum, bu bağlantılı sorunun bir kopyası değil . Yukarıdaki "işaretleri" nasıl kaldırabiliriz acaba?
Alan Cabrera

Görebileceğim böyle bir bağlantı yok.
Alan Cabrera

Yanıtlar:


252

Bize dil vermezsiniz, ancak regex lezzet desteğiniz iddianın arkasına bakarsa , ihtiyacınız olan şey budur:

.*(?<!a)$

(?<!a)dizenin (veya mdeğiştiricili satırın ) sonundan önce "a" karakterinin bulunmamasını sağlayan, ihmal edilmiş bir geriye dönük iddiasıdır .

Regexr'de buraya bakın

Dizeyi kontrol ettiğinden ve bir karakter sınıfı olmadığından bunu diğer karakterlerle de kolayca genişletebilirsiniz.

.*(?<!ab)$

Bu "ab" ile bitmeyen herhangi bir şeyle eşleşir, bakınız Regexr


1
RegexPAL bilmiyorum, ancak regexes tüm dillerde farklıdır ve geriye dönük iddialar herkes tarafından desteklenmeyen gelişmiş bir özelliktir.
stema

7
regexpal bir javascript tabanlı regex test cihazıdır ve javascript üzgün
bakışları

Regexr (javascript) üzerinde görünümler desteklenmiyor
Stealth Rabbi

1
JS'de bakış açılarının olmaması beni ağlatıyor. Sunucu tarafı yapıyorsanız, muhtemelen PCRE modülünü NPM'de veya doğrudan kullanmak için benzer bir şekilde kullanabilirsiniz (bu bir dizi bağlamadır, bu yüzden ön uç kullanabileceğinizi düşünmüyorum)
Eirik Birkeland

Daha ileri bakış / ileri görüş iddiaları: stackoverflow.com/q/2973436/12484
Jon Schneider

76

Not ( ^) sembolünü kullanın :

.*[^a]$

^Sembolü parantezlerin başına koyarsanız, "parantez içindeki şeyler hariç her şey" anlamına gelir. $sadece sonuna kadar bir çapa.

Birden fazla karakter için , hepsini kendi karakter kümelerine koyun:

.*[^a][^b]$

1
+1, bunun boş dizeyle eşleşmediği konusunda uyarılır (amaçlandığı gibi olabilir veya olmayabilir), bu nedenle anlam "parantez içinde olmayan herhangi bir karakter" dir.
Fred Foo

3
@ 0A0D: boşluk içeren bir dize boş bir dize değil.
Fred Foo

7
@ 0A0D Aslında, bu tartışmaya açık değil, bu bir gerçek
tckmn

8
@Doorknob: bu uyuşmuyor aeveya cb.
Fred Foo

1
Hayır, bu "acb" a da izin vermezdi.
Menno

49

".Tmp" ile bitmeyen dosyaları aramak için aşağıdaki normal ifadeyi kullanırız:

^(?!.*[.]tmp$).*$

Regex Tester ile test edildiğinde aşağıdaki sonuç elde edilir:

resim açıklamasını buraya girin


1
Bu ilginç, neden işe yarayıp ^.*(?![.]tmp$)yaramadığı hakkında bir fikir var mı?
asukasz Zaroda

4
Erken .*döneminiz zaten tüm dizeyle eşleşir, bu nedenle kalan hariç tutma artık çalışmaz.
FiveO

Benim amacım için bu işe yaradı ve diğer cevaplar olmadı. Teşekkürler!
David Moritz

8
.*[^a]$

yukarıdaki normal ifade ile bitmeyen dizelerle eşleşecektir a.


Orijinal örnek davamla tam olarak eşleşmediği için sorumu uzattım. Çözebilir misin?
Menno

5

Bunu dene

/.*[^a]$/

[]Bir karakter sınıfını belirtir ve ^tersine döndüğü karakter sınıfı herşeyi ama bir maç için a.


1

Soru eski ama burada benim yayınladığım daha iyi bir çözüm bulamadım. Tüm USB sürücüleri bulun, ancak bölümleri listelemeyin , böylece "parça [0-9]" u sonuçlardan kaldırın. Sonunda iki grep yaptım, sonuncusu sonucu reddediyor:

ls -1 /dev/disk/by-path/* | grep -P "\-usb\-" | grep -vE "part[0-9]*$"

Bu benim sistemimde sonuçlanır:

pci-0000:00:0b.0-usb-0:1:1.0-scsi-0:0:0:0

Sadece bölümleri istersem yapabilirdim:

ls -1 /dev/disk/by-path/* | grep -P "\-usb\-" | grep -E "part[0-9]*$"

Nereden alacağım:

pci-0000:00:0b.0-usb-0:1:1.0-scsi-0:0:0:0-part1
pci-0000:00:0b.0-usb-0:1:1.0-scsi-0:0:0:0-part2

Ve yaptığım zaman:

readlink -f /dev/disk/by-path/pci-0000:00:0b.0-usb-0:1:1.0-scsi-0:0:0:0

Alırım:

/dev/sdb

1

Bakışları kullanabiliyorsanız, kabul edilen cevap iyidir. Ancak, bu sorunu çözmek için başka bir yaklaşım daha vardır.

Bu soru için yaygın olarak önerilen normal ifadeye bakarsak:

.*[^a]$

Neredeyse işe yaradığını göreceğiz . Biraz rahatsız edici olabilecek boş bir dize kabul etmez. Ancak, tek bir karakterle uğraşırken bu küçük bir sorundur. Ancak, tüm dizeyi (örn. "Abc") hariç tutmak istiyorsak, o zaman:

.*[^a][^b][^c]$

yapmayacak. Örneğin ac'ı kabul etmez.

Yine de bu sorunun kolay bir çözümü var. Basitçe şunu söyleyebiliriz:

.{,2}$|.*[^a][^b][^c]$

veya daha genelleştirilmiş sürüm:

.{,n-1}$|.*[^firstchar][^secondchar]$ burada n sen (yasaklayamamaktadırlar istediğiniz dize uzunluğu abco 3 var) ve firstchar, secondchar... ilk olarak, sizin dize ikinci ... inci karakter (için abcolurdu a, o zaman b, o zaman c).

Bu, yasaklamayacağımız metinden daha kısa bir dizenin bu metni tanım olarak içeremeyeceği basit bir gözlemden gelir. Bu yüzden ya daha kısa olan ("ab" "abc" değildir) ya da kabul etmemiz için yeterince uzun ama sonu olmayan bir şeyi kabul edebiliriz.

Aşağıda, .jpg olmayan tüm dosyaları silecek bir bulma örneği verilmiştir:

find . -regex '.{,3}$|.*[^.][^j][^p][^g]$' -delete


.{,2}$|.*[^a][^b][^c]$uyuşmuyorccc
psalaets

0

--- Bir ile biten bir şey eşleşen şey .*a$sen regex eşleştiğinde Yani, koşulu inkâr veya alternatif olarak da yapabilirsiniz olan araçlar şey.*[^a]$[^a]not a


0

Eğer kullanıyorsanız grepveya sedsözdizimi biraz farklı olacaktır. Sıralı [^a][^b]yöntemin burada çalışmadığına dikkat edin :

balter@spectre3:~$ printf 'jd8a\n8$fb\nq(c\n'
jd8a
8$fb
q(c
balter@spectre3:~$ printf 'jd8a\n8$fb\nq(c\n' | grep ".*[^a]$"
8$fb
q(c
balter@spectre3:~$ printf 'jd8a\n8$fb\nq(c\n' | grep ".*[^b]$"
jd8a
q(c
balter@spectre3:~$ printf 'jd8a\n8$fb\nq(c\n' | grep ".*[^c]$"
jd8a
8$fb
balter@spectre3:~$ printf 'jd8a\n8$fb\nq(c\n' | grep ".*[^a][^b]$"
jd8a
q(c
balter@spectre3:~$ printf 'jd8a\n8$fb\nq(c\n' | grep ".*[^a][^c]$"
jd8a
8$fb
balter@spectre3:~$ printf 'jd8a\n8$fb\nq(c\n' | grep ".*[^a^b]$"
q(c
balter@spectre3:~$ printf 'jd8a\n8$fb\nq(c\n' | grep ".*[^a^c]$"
8$fb
balter@spectre3:~$ printf 'jd8a\n8$fb\nq(c\n' | grep ".*[^b^c]$"
jd8a
balter@spectre3:~$ printf 'jd8a\n8$fb\nq(c\n' | grep ".*[^b^c^a]$"

FWIW, JavaScript sözdizimi olduğunu düşünüyorum Regex101 aynı sonuçları buluyorum.

Kötü: https://regex101.com/r/MJGAmX/2
İyi: https://regex101.com/r/LzrIBu/2

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.