Açgözlü vs açgözlü olmayan
Normalde regex'te tekrarlama açgözlüdür : mümkün olduğu kadar çok tekrarla eşleşmeye çalışırlar ve bu işe yaramazsa ve geri gitmeleri gerektiğinde, tüm desenin eşleşmesi gerçekleşene kadar bir seferde daha az tekrarla eşleşmeye çalışırlar. bulundu. Sonuç olarak, bir maç nihayet gerçekleştiğinde, açgözlü bir tekrar mümkün olduğu kadar çok tekrarla eşleşir .
?
İçine bu davranışı değiştirir miktar belirleyici bir tekrarı olarak olmayan açgözlü da adlandırılan, isteksiz ( örn Java ) (ve bazen "tembel"). Buna karşılık, bu tekrarlama ilk önce mümkün olduğunca az sayıda tekrar eşleştirmeye çalışacaktır ve bu işe yaramazsa ve geri takip etmek zorunda kaldıklarında, bir kez daha bir rept ile eşleşmeye başlarlar. Sonuç olarak, bir maç nihayet gerçekleştiğinde, isteksiz bir tekrarlama mümkün olduğunca az tekrarla eşleşir .
Referanslar
Örnek 1: A'dan Z'ye
Bu iki örüntüyü karşılaştıralım: A.*Z
ve A.*?Z
.
Aşağıdaki girdi verildiğinde:
eeeAiiZuuuuAoooZeeee
Kalıplar aşağıdaki eşleşmeleri verir:
Önce ne A.*Z
işe odaklanalım . İlk eşleşti zaman A
, .*
açgözlü, ilk denemeden olmanın birçok olarak eşleşecek şekilde .
mümkün olduğunca.
eeeAiiZuuuuAoooZeeee
\_______________/
A.* matched, Z can't match
Yana Z
, motor geri adım attığı uymuyor ve .*
sonra bir daha az eşleşmesi gerekir .
:
eeeAiiZuuuuAoooZeeee
\______________/
A.* matched, Z still can't match
Bu birkaç kez daha olur, nihayet buna gelene kadar:
eeeAiiZuuuuAoooZeeee
\__________/
A.* matched, Z can now match
Şimdi Z
eşleşebilir, böylece genel desen eşleşir:
eeeAiiZuuuuAoooZeeee
\___________/
A.*Z matched
Buna karşılık, A.*?Z
ilk olarak isteksiz tekrarlama .
mümkün olduğunca az eşleşir ve sonra .
gerektiği kadar alır. Bu, girdide neden iki eşleşme bulduğunu açıklar.
İşte bu iki modelin eşleştiğinin görsel bir temsili:
eeeAiiZuuuuAoooZeeee
\__/r \___/r r = reluctant
\____g____/ g = greedy
Örnek: Alternatif
Birçok uygulamada, yukarıdaki girişteki iki eşleşme istenen şeydir, bu nedenle aşırı eşleşmeyi önlemek .*?
için açgözlü yerine bir isteksiz kullanılır .*
. Bununla birlikte, bu özel model için, ihmal edilmiş karakter sınıfı kullanan daha iyi bir alternatif vardır.
Örüntü A[^Z]*Z
ayrıca A.*?Z
yukarıdaki girdinin örüntüsü ile aynı iki eşleşmeyi bulur ( ideone.com'da görüldüğü gibi ). reddedilen karakter sınıfı[^Z]
olarak adlandırılan şeydir : başka bir şeyle eşleşmez .Z
İki desen arasındaki temel fark performanstır: daha katı olmak gerekirse, reddedilen karakter sınıfı belirli bir girdi için yalnızca bir yolla eşleşebilir. Bu desen için açgözlü veya isteksiz değiştirici kullanmanız önemli değildir. Aslında, bazı tatlarda, daha da iyi yapabilir ve hiç geri takip etmeyen iyelik nicelleştirici denilen şeyi kullanabilirsiniz.
Referanslar
Örnek 2: A'dan ZZ'ye
Bu örnek açıklayıcı olmalıdır: açgözlü, isteksiz ve reddedilmiş karakter sınıfı kalıplarının aynı girdi göz önüne alındığında nasıl farklı eşleştiğini gösterir.
eeAiiZooAuuZZeeeZZfff
Bunlar yukarıdaki girdinin eşleşmeleri:
Eşleştiklerinin görsel bir temsili:
___n
/ \ n = negated character class
eeAiiZooAuuZZeeeZZfff r = reluctant
\_________/r / g = greedy
\____________/g
İlgili konular
Bunlar, ilgi çekici olabilecek bazı konuları kapsayan yığın akışı hakkında soru ve cevaplara bağlantılardır.
Açgözlü bir tekrar diğerini geçebilir