在Scala的解析器组合器(特别是JavaTokensParser)中,有一个定义stringLiteral,它匹配类似Java的字符串.
def stringLiteral: Parser[String] =
("\""+"""([^"\p{Cntrl}\\]|\\[\\'"bfnrt]|\\u[a-fA-F0-9]{4})*"""+"\"").r
Run Code Online (Sandbox Code Playgroud)
不幸的是,这个正则表达式不适用于长字符串.有没有人知道这样做的可重用实现,还是对空格效率更高的正则表达式的修改?
有趣的问题!!
\n\n刚刚玩了一下,并得出以下结论:
\n\nval 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 对,至少在我的默认配置中是这样。
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
酷刑案件。秘密是使用贪婪所有格修饰符,这基本上不需要回溯,因此也关闭了递归。
val r = (""""([^"\\p{Cntrl}\\\\]*+(?:\\\\[\\\\\'"bfnrt])*+(?:\\\\u[a-fA-F0-9]{4})*+)*+"""").r\n
Run Code Online (Sandbox Code Playgroud)\n\n解决方案的本质是在每次匹配某些东西时尽可能多地尝试和咀嚼。
\n\nscala> 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 归档时间: |
|
查看次数: |
522 次 |
最近记录: |