Normal ifadenin bir parçası nasıl eşleştirilir, ancak yakalanmaz?


209

Dizelerin bir listesi var. Bazıları formda 123-...456. Değişken kısım "..." şöyle olabilir:

  • "elma" dizesi ve ardından kısa çizgi, ör. 123-apple-456
  • "muz" dizesini ve ardından kısa çizgi, ör. 123-banana-456
  • boş bir dize, örneğin 123-456(yalnızca bir tire işareti olduğunu unutmayın)

"Elma" veya "muz" dışındaki herhangi bir kelime geçersiz.

Bu üç durum için sırasıyla "elma", "muz" ve "" ile eşleştirmek istiyorum. Kısa çizgiyi yakalamak istemediğimi , ancak her zaman eşleştirmek istediğimi unutmayın . Dize 123-...456yukarıda açıklandığı gibi değilse , hiçbir eşleşme yoktur.

Bunu yapmak için nasıl düzenli bir ifade yazarım? İleriye, geriye, göze, ve yakalamayan gruplara izin veren bir lezzetim olduğunu varsayın.


Buradaki en önemli gözlem, "elma" veya "muz" olduğunda, sondaki kısa çizginizin de olması gerektiğidir , ancak eşleştirmek istemezsiniz. Boş dizeyle eşleştiğinizde , sondaki tire işareti olmamalıdır . Bu iddiayı çevreleyen bir regex doğru olacaktır.


Kısa çizgiler dışında her şeyi eşleştirmek ister misiniz?
BrunoLM

Yanıtlar:


285

Bir şeyi yakalamamanın tek yolu etrafındaki iddiaları kullanmaktır :

(?<=123-)((apple|banana)(?=-456)|(?=456))

Çünkü yakalamayan gruplarda(?:…) bile tüm düzenli ifade eşleşen içeriklerini yakalar. Ama bu düzenli ifade sadece maçları appleya bananada öncesinde eğer 123-ve ardından -456ya da öncesinde eğer boş dizge ile eşleşir 123-ve ardından 456.

|Lookaround  |    Name      |        What it Does                       |
-----------------------------------------------------------------------
|(?=foo)     |   Lookahead  | Asserts that what immediately FOLLOWS the |
|            |              |  current position in the string is foo    |
-------------------------------------------------------------------------
|(?<=foo)    |   Lookbehind | Asserts that what immediately PRECEDES the|
|            |              |  current position in the string is foo    |
-------------------------------------------------------------------------
|(?!foo)     |   Negative   | Asserts that what immediately FOLLOWS the |
|            |   Lookahead  |  current position in the string is NOT foo|
-------------------------------------------------------------------------
|(?<!foo)    |   Negative   | Asserts that what immediately PRECEDES the|
|            |   Lookbehind |  current position in the string is NOT foo|
-------------------------------------------------------------------------

1
+1 - Bu durumda, grup 0 yerine grup 1'i kullanarak bu sorunu çözebilirsiniz, ancak bu mükemmel (ve ince!) Bir ayrımdır.
Ben Blank

@Ben Blank: Kesinlikle “maç” ve “yakalama” nın nasıl yorumlandığına bağlıdır.
Gumbo

8
JavaScript desteklenmez, yay ! JS dostu bir yönteme sahip olmak güzel olurdu, ama hiç de fena değil, +0.5 (yuvarlama; D)
GiantCowFilms

Etrafa bakma iddialarını seviyorum! Bunlar Ruby ile de harika çalışıyor.
Rots

mükemmel bir çözüm, bunu seviyorum
Trần Quang Hiệp

15

Güncelleme: Germán Rodríguez Herrera'ya teşekkürler!

Javascript'te şunu deneyin: /123-(apple(?=-)|banana(?=-)|(?!-))-?456/

Sonucun grup 1'de olduğunu unutmayın

Debuggex Demosu


8

Deneyin:

123-(?:(apple|banana|)-|)456

Bu maç olacak apple, bananaya da boş bir dize ve bunu takip eden bir 0 ya da 1 tire olacak. Bir yakalama grubuna ihtiyaç duymama konusunda yanılmışım. Aptal bana.


Bu, örneğin "123-coconut-456" ile eşleştiği için doğru değildir.
David Stone

Daha genel istediđini sanmýţtým ... düzeltildi.
Thomas

5

Yanıtlardan birini değiştirdim (@ op1ekun tarafından):

123-(apple(?=-)|banana(?=-)|(?!-))-?456

Bunun nedeni, @ op1ekun'un cevabının elmadan "123-apple456"sonra tire işareti olmadan da eşleşmesidir .


3

Bunu dene:

/\d{3}-(?:(apple|banana)-)?\d{3}/

1
Bu, örneğin "123-coconut-456" ile eşleştiği için doğru değildir.
David Stone

@david: "muz" örneğinizden farkı nedir?
SilentGhost

@SilentGhost: Ben sadece yakalama istiyorum appleya banana"" veya. Dediğim gibi diğer tüm değerler geçersiz.
David Stone

sry, bu durumda: / \ d {3} - (? :( elma | muz) -)? \ d {3} /
slosd

1
Bu örneğin gösterdiği, ileriye ve geriye doğru bakmadan ele geçirmeyen bir gruba sahip olmanın mümkün olduğudur.
Vince Panuccio

0

\KMaçta sayı bloklarının dahil edilmesini önlemek için eşleşme konumlarını sıfırlamak için kullanılan @Gumbo ifadesinin bir varyasyonu . PCRE regex tatlarında kullanılabilir.

123-\K(?:(?:apple|banana)(?=-456)|456\K)

Maçlar:

Match 1  apple
Match 2  banana
Match 3

-3

Şimdiye kadar en basit (python için çalışır) '123-(apple|banana)-?456'.


1
Bu eşleşir, 123-apple456böylece doğru olmaz.
Loren
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.