我想匹配三元组中包含的字符串"
- 可能包含换行符的引号,以及不包含任何换行符的引号"""
-除了最开始和最后的子字符串。
有效示例:
"""foo
bar "baz" blah"""
无效示例:
"""foo bar """ baz"""
我尝试使用以下正则表达式(如 JavaString
文字):
"(?m)\"\"\"(?:[^\"]|(?:\"[^\"])|(?:\"\"[^\"]))*\"\"\""
它似乎适用于简短的例子。但是,在较长的示例中,例如由千行组成的字符串hello world
,它给了我一个StackOverflowError
.
用于重现错误的 Scala 片段
import java.util.regex.{Pattern, Matcher}
val text = "\"" * 3 + "hello world \n" * 1000 + "\"" * 3
val p = Pattern.compile("(?m)\"\"\"(?:[^\"]|(?:\"[^\"])|(?:\"\"[^\"]))*\"\"\"")
println(p.matcher("\"\"\" foo bar baz \n baz bar foo \"\"\"").lookingAt())
println(p.matcher(text).lookingAt())
(注意:本地测试,Scastie 超时;或者可能将 1000 减少到更小的数字?)。
产生相同错误的 Java 片段
import java.util.regex.Pattern;
import java.util.regex.Matcher;
class RegexOverflowMain {
public static void main(String[] args) {
StringBuilder bldr = new StringBuilder();
bldr.append("\"\"\"");
for (int i = 0; i < 1000; i++) {
bldr.append("hello world \n");
}
bldr.append("\"\"\"");
String text = bldr.toString();
Pattern p = Pattern.compile("(?m)\"\"\"(?:[^\"]|(?:\"[^\"])|(?:\"\"[^\"]))*\"\"\"");
System.out.println(p.matcher("\"\"\" foo bar baz \n baz bar foo \"\"\"").lookingAt());
System.out.println(p.matcher(text).lookingAt());
}
}
Question
知道如何使这个“堆栈安全”,即有人可以找到一个接受相同语言但不产生StackOverflowError
当输入到 Java 正则表达式 API 时?
我不在乎解决方案是 Scala 还是 Java(或其他),只要使用相同的底层 Java 正则表达式库即可。