Neden bu kadar uzun maç için sürer? Bir hata mı?
Web uygulaması, /123,456,789
yani, belirli bir URL maç için ihtiyacım var ve bu normal ifadenin desen eşleşmesi için yazdı:
r'(\d (,)?) /$'
Desen test ederken değerlendirmek için, hatta birkaç dakika sonra görünmüyor fark ettim:
re.findall(r'(\d (,)?) /$', '12345121,223456,123123,3234,4523,523523')
Beklenen sonuç kibrit yoktu.
Bu ifade, ancak, hemen hemen (sondaki eğik çizgi unutmayın) yürütür:
re.findall(r'(\d (,)?) /$', '12345121,223456,123123,3234,4523,523523/')
Bu bir hata mı?
CEVAP
Olmayan maç dize ne kadar bağlı olduğundan işlem üstel bir miktar neden olacak catastrophic backtracking bazı şeyler oluyor. Bu, iç içe geçmiş tekrarlar ve isteğe bağlı virgül bazı düzenli ifade motorları bu gereksiz tekrarı tüm teşebbüs ile bir maç olmayacağını belirleyebilirsiniz bile olsa) ile bir ilgisi yoktur. Bu ifadeyi optimize ederek çözülür.
Bu sadece 1 basamak ya da virgül, eğik çizgi ve diziyi sonuna kadar takip aramaktır yapmanın en kolay yolu: [\d,] /$
. Ancak, o ,123,,4,5/
gibi bir şey için izin vermesi beri mükemmel değildir.
İlk denemede biraz optimize edilmiş bir sürümünü kullanabilirsiniz bunun için: (?:\d,?) /$
. İlk olarak, gerekli değildir yinelenen grubu non-capturing ((?:...)
) yaptım ama bir sağlar"". temiz maçBir sonraki, ve sadece önemli adım, grup zaten yinelenen olduğundan grubunun \d
içinde tekrarlayıp durdum.Son olarak, ?
sadece son karakteri etkilediği için isteğe bağlı etrafında gereksiz grubu ,
çıkardım. Oldukça fazla.
Bu hala negative lookbehind ile özgün düzenli geliştirdim garip bir string 1,2,3,/
, bunun heck bu yüzden maç olabilir: (?:\d,?) (?<!,)/$
. Bu /
sondaki önce virgül doğrudan hiçbir iddia edecektir.
Neden Eclipse Maven bağımlılıkları gün...
Neden&; dizi yineleme için... "* o kad...
Neden C derleme bu kadar uzun sürüyor?...
Ne kadar uzun işaretsiz bir tamsayı(iş...
Ne kadar çok uzun dizin adları işlemek...