要匹配Java字符串的正则表达式

要匹配Java字符串的正则表达式,java,regex,scala,Java,Regex,Scala,在Scala的解析器组合器(尤其是)中,有一个与类Java字符串匹配的定义 def stringLiteral: Parser[String] = ("\""+"""([^"\p{Cntrl}\\]|\\[\\'"bfnrt]|\\u[a-fA-F0-9]{4})*"""+"\"").r 不幸的是,这个正则表达式。有人知道这样的可重用实现吗,或者对regex的修改更节省空间吗?有趣的问题 我只是玩弄了一下,得出了以下结论: val r = ("\"" + "(?:[

在Scala的解析器组合器(尤其是)中,有一个与类Java字符串匹配的定义

def stringLiteral: Parser[String] =
              ("\""+"""([^"\p{Cntrl}\\]|\\[\\'"bfnrt]|\\u[a-fA-F0-9]{4})*"""+"\"").r
不幸的是,这个正则表达式。有人知道这样的可重用实现吗,或者对regex的修改更节省空间吗?

有趣的问题

我只是玩弄了一下,得出了以下结论:

val r = ("\"" + "(?:[^\"\\p{Cntrl}\\\\]*|(?:\\\\(?:[\\\\'\"bfnrt]|u[a-fA-F0-9]{4}))*)*" + "\"").r
注意:上面的正则表达式是从第一个版本开始修复的……前导“\”和尾随字符都需要重复,而不仅仅是我最初使用的尾随字符

Edit:找到了一个更高效的正则表达式。使用以下方法,它可以解析最多950对
\\ns
的字符串,而不是原始字符串,它只能解析556,至少在我的默认配置中是这样

val r = ("\"" + "(?:[^\"\\p{Cntrl}\\\\]*|\\\\[\\\\'\"bfnrt]|\\\\u[a-fA-F0-9]{4})*" + "\"").r
编辑2:根据@schmmd的评论,我有一个更好的正则表达式。这个可以解析2500
\ns
酷刑案。秘密是使用贪婪的所有格修饰符,这基本上关闭了回溯的需要,因此也关闭了递归

val r = (""""([^"\p{Cntrl}\\]*+(?:\\[\\'"bfnrt])*+(?:\\u[a-fA-F0-9]{4})*+)*+"""").r
解决方法的本质是每次你匹配某样东西时尽可能多地咀嚼

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

更新:A已提交给scala。它被接受了。

您的正则表达式很好,但对我来说,删除所有的析取是有意义的。但它仍然会溢出到您的
“\\ns”*2500
上<代码>(“\”“+”([^”\p{Cntrl}\\\\]*(?:\\[\''bfnrt])*(?:\\u[a-fA-F0-9]{4})**“+”).r。将我所有的克莱恩星转换为占有克莱恩星可以提供更好的性能。(“\\+”“”([^”\p{Cntrl}\]*+(?:\[\\'“bfnrt])*+(?:\\u[a-fA-F0-9]{4})*+)*+“+”“+”)。r@schmmd你是对的!所有格运算符确实是答案。你甚至可以在原始答案中使用它,它也解决了这个问题。我现在接受你的答案。我很想听到一个为其中的模式进行解析器的库,以及将解析后的Java字符串转换为
string
实例的方法。我真的希望这能提交给Scala库。