[英]Regex to match Java String
在Scala的解析器組合器(尤其是JavaTokensParser )中,有一個stringLiteral定義,它與類似Java的字符串相匹配。
def stringLiteral: Parser[String] =
("\""+"""([^"\p{Cntrl}\\]|\\[\\'"bfnrt]|\\u[a-fA-F0-9]{4})*"""+"\"").r
不幸的是,此正則表達式不適用於長字符串 。 有人知道這樣做的可重用實現,還是對正則表達式的修改更節省空間?
有趣的問題!
只是玩這個,並提出了以下內容:
val r = ("\"" + "(?:[^\"\\p{Cntrl}\\\\]*|(?:\\\\(?:[\\\\'\"bfnrt]|u[a-fA-F0-9]{4}))*)*" + "\"").r
注意:上面的正則表達式是從第一個版本開始修復的……前導'\\'和結尾字符都需要重復,而不僅僅是我原來的結尾字符!
編輯:找到一個更有效的正則表達式。 使用以下命令,它可以解析最多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
更新: 拉動請求已提交給Scala人員。 並被接受。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.