SORU
22 EYLÜL 2014, PAZARTESİ


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
22 EYLÜL 2014, PAZARTESİ


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.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • EatingIn

    EatingIn

    12 EKİM 2013
  • Gee Cee

    Gee Cee

    1 AĞUSTOS 2009
  • Matthew Smith

    Matthew Smit

    24 Mayıs 2010