2013-10-07 25 views

cevap

3

İlginç bir problem!

Sadece bu etrafında oynanan ve ile geldi şunlardır:

val r = ("\"" + "(?:[^\"\\p{Cntrl}\\\\]*|(?:\\\\(?:[\\\\'\"bfnrt]|u[a-fA-F0-9]{4}))*)*" + "\"").r 

Not: Yukarıdaki regex hem ... ilk sürümden giderilmiştir lider '\' ve sondaki karakterler gerekir Ben sadece orijinal olarak vardı gibi sadece arkasındaki karakterleri tekrarlamak!

Düzenleme: daha verimli düzenli ifade Bulundu. Aşağıdakileri kullanarak, en az varsayılan yapılandırmamda 556'yı ayrıştırabilen orijinalin aksine 950 \\ns çiftine kadar bir dizeyi ayrıştırabilir.

val r = ("\"" + "(?:[^\"\\p{Cntrl}\\\\]*|\\\\[\\\\'\"bfnrt]|\\\\u[a-fA-F0-9]{4})*" + "\"").r 

Düzenleme 2: @schmmd gelen yorum dayanarak, ben daha iyi bir düzenli ifade var. Bu, 2500 \ns işkence vakasını ayrıştırabilir. Sırr, açgözlü iyelik değiştiricisini kullanmaktır, bu temel olarak geriye dönük bir geri dönüşe ihtiyaç duymaz ve bu da özyinelemeyi kapatır.

val r = (""""([^"\p{Cntrl}\\]*+(?:\\[\\'"bfnrt])*+(?:\\u[a-fA-F0-9]{4})*+)*+"""").r 

Çözümün özü, bir şeyle eşleştiğiniz her seferde olabildiğince fazla çiğnemek ve çiğnemek.

scala> val r = (""""([^"\p{Cntrl}\\]*+(?:\\[\\'"bfnrt])*+(?:\\u[a-fA-F0-9]{4})*+)*+"""").r 
r: scala.util.matching.Regex = "([^"\p{Cntrl}\\]*+(?:\\[\\'"bfnrt])*+(?:\\u[a-fA-F0-9]{4})*+)*+" 

scala> r.pattern.matcher("\"" + "\\ns" * 2500 + "\"").lookingAt 
res4: Boolean = true 

scala> r.pattern.matcher("\"" + "s" * 2500 + "\"").lookingAt 
res5: Boolean = true 

Güncelleme: A pull request scala millet sunuldu. Ve kabul edildi.

+1

Java olsaydı yerleşik bir Thompson NFA'ler kullanılan regex uygulaması ... – schmmd

+0

Kişisel regex iyidir, ama tüm kopukluklar kaldırmak için bana mantıklı. Yine de, "\\ ns" * 2500'ünüzde hala taşıyor. '(" \ "" + "" "([^" \ p {Cntrl} \\] * (?: \\ [\\ '"bfnrt]) * (?: \\ u [a-fA-F0- 9] {4}) *) * "" "+" \ "") r'. – schmmd

+0

Tüm Kleene yıldızlarını cazip Kleene yıldızlarına dönüştürmek daha iyi performans sağlar. ("\" "+" "" ([^ "\ p {Cntrl} \\] * + (?: \\ [\\ '" bfnrt]) * + (?: \\ u [a-fA-F0 -9] {4}) * +) * + "" "+" \ "") r – schmmd