正则表达式匹配Java字符串

sch*_*mmd 8 java regex scala

在Scala的解析器组合器(特别是JavaTokensParser)中,有一个定义stringLiteral,它匹配类似Java的字符串.

def stringLiteral: Parser[String] =
              ("\""+"""([^"\p{Cntrl}\\]|\\[\\'"bfnrt]|\\u[a-fA-F0-9]{4})*"""+"\"").r
Run Code Online (Sandbox Code Playgroud)

不幸的是,这个正则表达式不适用于长字符串.有没有人知道这样做的可重用实现,还是对空格效率更高的正则表达式的修改?

Pau*_*and 3

有趣的问题!!

\n\n

刚刚玩了一下,并得出以下结论:

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

注意:上面的正则表达式是从第一个版本 \xe2\x80\xa6 开始修复的,前导 \'\\\' 和尾随字符都需要重复,而不仅仅是我最初拥有的尾随字符!

\n\n

编辑:找到了更有效的正则表达式。使用以下内容,它可以解析最多 950 对的字符串\\\\ns,而原始版本只能解析 556 对,至少在我的默认配置中是这样。

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

编辑2:根据@schmmd的评论,我有一个更好的正则表达式。这个可以解析2500\\ns酷刑案件。秘密是使用贪婪所有格修饰符,这基本上不需要回溯,因此也关闭了递归。

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

解决方案的本质是在每次匹配某些东西时尽可能多地尝试和咀嚼。

\n\n
scala> val r = (""""([^"\\p{Cntrl}\\\\]*+(?:\\\\[\\\\\'"bfnrt])*+(?:\\\\u[a-fA-F0-9]{4})*+)*+"""").r\nr: scala.util.matching.Regex = "([^"\\p{Cntrl}\\\\]*+(?:\\\\[\\\\\'"bfnrt])*+(?:\\\\u[a-fA-F0-9]{4})*+)*+"\n\nscala> r.pattern.matcher("\\"" + "\\\\ns" * 2500 + "\\"").lookingAt\nres4: Boolean = true\n\nscala> r.pattern.matcher("\\"" + "s" * 2500 + "\\"").lookingAt\nres5: Boolean = true\n
Run Code Online (Sandbox Code Playgroud)\n\n

更新:取请求已提交给 scala 人员。它被接受了。

\n