Yanıtlar:
Açgözlü mümkün olduğunca tüketecektir. Gönderen http://www.regular-expressions.info/repeat.html biz HTML etiketlerini maç için çalışmakla örneğe bakın <.+>
. Aşağıdakilere sahip olduğunuzu varsayalım:
<em>Hello World</em>
Bunu düşünebilir <.+>
( .
vasıta olmayan herhangi satır karakteri ve +
araçlar bir ya da daha ) sadece eşleşir <em>
ve </em>
gerçekte çok hırslı olacak zaman, ve ilk gitmek <
son için >
. Bu, <em>Hello World</em>
istediğin yerine eşleşeceği anlamına gelir .
Tembel ( <.+?>
) yapmak bunu engelleyecektir. Ekleyerek ?
sonra +
, biz tekrar söylemek mümkün olduğunca az zamanları gibi ilk böylece >
biz eşleştirme durdurmak istediğimiz yere rastlar vardır.
Düzenli İfadeleri keşfetmenize yardımcı olacak harika bir araç olan RegExr'i indirmenizi öneririm - her zaman kullanıyorum.
<[^>]+>
regex101.com/r/lW0cY6/1
'Açgözlü' , mümkün olan en uzun dizeyle eşleşmek anlamına gelir.
'Tembel' mümkün olan en kısa karakter dizisiyle eşleşir.
Örneğin, açgözlü h.+l
maçlar 'hell'
içinde 'hello'
ama tembel h.+?l
maçlar 'hel'
.
h.+l
maçlar 'helol'
içinde 'helolo'
ama tembel h.+?l
maçlar 'hel'
.
x?
anlamına gelir . Eşleşen bir şey bulduktan sonra durmak anlamına gelir - tembel eşleme. x
+?
?
isteğe bağlı ve +?
tembel anlamına gelir. Bu nedenle \+?
araçlar +
isteğe bağlıdır.
+-------------------+-----------------+------------------------------+
| Greedy quantifier | Lazy quantifier | Description |
+-------------------+-----------------+------------------------------+
| * | *? | Star Quantifier: 0 or more |
| + | +? | Plus Quantifier: 1 or more |
| ? | ?? | Optional Quantifier: 0 or 1 |
| {n} | {n}? | Quantifier: exactly n |
| {n,} | {n,}? | Quantifier: n or more |
| {n,m} | {n,m}? | Quantifier: between n and m |
+-------------------+-----------------+------------------------------+
Ekle ? tembel hale getirmek için bir niceleyiciye.
Örnek:
test dizesi: stackoverflow
açgözlü reg ifade : s.*o
output: stackoverflo w
tembel reg ifade : s.*?o
output: stacko verflow
re.match('(f)?(.*)', 'food').groups()
için re.match('(f)??(.*)', 'food').groups()
. İkincisi, (f)??
olsa bile önde gelen 'f' ile eşleşmeyecek. Dolayısıyla 'f' ikinci '. *' Yakalama grubu tarafından eşleştirilecektir. Eminim '{n}?' İle bir örnek oluşturabilirsiniz? çok. Kuşkusuz bu ikisi çok nadiren kullanılır.
Açgözlü, ifadenizin mümkün olduğunca büyük bir grupla eşleşeceği anlamına gelir, tembel anlamına gelir, mümkün olan en küçük grupla eşleşir. Bu dize için:
abcdefghijklmc
ve bu ifade:
a.*c
Açgözlü bir maç tüm dizeyle eşleşecek ve tembel bir maç sadece ilkiyle eşleşecek abc
.
Bildiğim kadarıyla, çoğu regex motoru varsayılan olarak açgözlü. Sayısallaştırıcının sonuna bir soru işareti eklemek tembel eşleşmeyi etkinleştirir.
@Andre S'nin yorumda belirtildiği gibi.
Açgözlü ve tembel olanlar için aşağıdaki örneğe bakın.
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Test {
public static void main(String args[]){
String money = "100000000999";
String greedyRegex = "100(0*)";
Pattern pattern = Pattern.compile(greedyRegex);
Matcher matcher = pattern.matcher(money);
while(matcher.find()){
System.out.println("I'm greeedy and I want " + matcher.group() + " dollars. This is the most I can get.");
}
String lazyRegex = "100(0*?)";
pattern = Pattern.compile(lazyRegex);
matcher = pattern.matcher(money);
while(matcher.find()){
System.out.println("I'm too lazy to get so much money, only " + matcher.group() + " dollars is enough for me");
}
}
}
I'm greeedy and I want 100000000 dollars. This is the most I can get.
I'm too lazy to get so much money, only 100 dollars is enough for me
Alınan www.regular-expressions.info
Açgözlülük : Açgözlü niceleyiciler önce jetonu mümkün olduğunca çok kez tekrarlamaya çalışır ve genel bir maç bulmak için motor geri tepme olarak yavaş yavaş eşleşmeleri bırakır .
Tembellik : Tembel nicelik belirteci ilk önce belirteci gerektiği kadar tekrar eder ve genel bir eşleşme bulmak için motor normal ifadeden geri çekildikçe maçı yavaş yavaş genişletir.
Gönderen Düzenli İfade
Düzenli ifadelerdeki standart niceleyiciler açgözlüdür, yani olabildiğince çok eşleşirler, sadece normal ifadenin geri kalanıyla eşleşmek için gerektiği kadar geri verirler.
Tembel bir nicelik belirteci kullanarak, ifade önce en düşük eşleşmeyi dener.
Açgözlü eşleme. Normal ifadelerin varsayılan davranışı açgözlü olmaktır. Bu, daha küçük bir parça sözdizimsel olarak yeterli olsa bile, bir desene uyuncaya kadar mümkün olduğunca çıkarmaya çalıştığı anlamına gelir.
Misal:
import re
text = "<body>Regex Greedy Matching Example </body>"
re.findall('<.*>', text)
#> ['<body>Regex Greedy Matching Example </body>']
İlk '>' oluşumuna kadar eşleştirmek yerine, tüm dizgeyi çıkardı. Bu, regex'in varsayılan açgözlü veya 'hepsini al' davranışıdır.
Tembel eşleme ise 'mümkün olduğunca az zaman alıyor'. Bu ?
, desenin sonuna a eklenerek gerçekleştirilebilir .
Misal:
re.findall('<.*?>', text)
#> ['<body>', '</body>']
Yalnızca ilk eşleşmenin alınmasını istiyorsanız, bunun yerine arama yöntemini kullanın.
re.search('<.*?>', text).group()
#> '<body>'
Kaynak: Python Normal İfade Örnekleri
Açgözlü, hiçbiri kalmayıncaya kadar deseninizi tüketeceği ve daha fazla bakamayacağı anlamına gelir.
Tembel, istediğiniz ilk desenle karşılaşır karşılaşmaz duracaktır.
Sık karşılaştığım yaygın bir örnek \s*-\s*?
normal ifadedir([0-9]{2}\s*-\s*?[0-9]{7})
Birincisi \s*
, sayılarla *
karşılaşıldıktan sonra mümkün olduğunca çok beyaz boşluk arayacak ve sonra bir çizgi karakteri "-" arayacak şekilde açgözlü olarak sınıflandırılmıştır . İkincisi \s*?
tembel olduğu için şimdiki zamandan dolayı *?
, ilk beyaz boşluk karakterine bakacak ve orada duracak demektir.
En iyi örnek olarak gösterilmiştir. Dize. 192.168.1.1
ve açgözlü bir regex \b.+\b
Bunun size 1'inci sekizlisini vereceğini düşünebilirsiniz, ancak aslında tüm dizeyle eşleşir. Neden? Çünkü. + Açgözlüdür ve açgözlü bir eşleşme 192.168.1.1
dizenin sonuna ulaşana kadar her karakteri eşleştirir . Önemli olan bu! Şimdi, 3. belirteç ( \b
) için bir eşleşme bulana kadar bir kerede bir karakter geri izlemeye başlar .
4GB metin dosyası ve 192.168.1.1 dizesi başlangıçtaysa, bu geri izlemenin nasıl bir soruna neden olacağını kolayca görebilirsiniz.
Normal olmayan açgözlü (tembel) yapmak için açgözlü aramanızdan sonra bir soru işareti koyun.
*?
??
+?
Şimdi olan şey, jeton 2 ( +?
) bir eşleşme bulur, normal ifade bir karakter boyunca hareket eder ve ardından \b
jeton 2 ( +?
) yerine bir sonraki jetonu ( ) dener . Böylece zekice sürünüyor.
Eğer oradaysa, gelip alırlar. Hepsini alacaklar:
Örneğin, IRS bu normal ifadeyle eşleşir: .*
$50,000
- IRS hepsini alacak. Bu açgözlü .*{4}?
ers
Bir örnek için buraya bakın: regexr.com/4t27f
Öte yandan, vergi iadesi talep edersem, IRS ani açgözlü olmaz ve bu nicelik belirtecini kullanırlar:
(.{2}?)([0-9]*)
Bu ifadeye karşı: $50,000
İlk grup ihtiyacı olmayan ve sadece eşleşir $5
- bu yüzden $5
geri ödeme alırım . Geri kalanı Sam amca tarafından boşa harcanmak üzere alınır.
Buraya bakınız: Açgözlü olmayan örnek .
Bir ifadenin belirli bölümlerini eşleştirmeye çalışıyorsanız önemli hale gelir. Bazen her şeyi eşleştirmek istemezsiniz.
aşağıdaki davranışı anlamaya çalışın:
var input = "0014.2";
Regex r1 = new Regex("\\d+.{0,1}\\d+");
Regex r2 = new Regex("\\d*.{0,1}\\d*");
Console.WriteLine(r1.Match(input).Value); // "0014.2"
Console.WriteLine(r2.Match(input).Value); // "0014.2"
input = " 0014.2";
Console.WriteLine(r1.Match(input).Value); // "0014.2"
Console.WriteLine(r2.Match(input).Value); // " 0014"
input = " 0014.2";
Console.WriteLine(r1.Match(input).Value); // "0014.2"
Console.WriteLine(r2.Match(input).Value); // ""