本文介紹了多行字符串文字的正則表達式生成`StackOverflow Error`的處理方法,對大家解決問題具有一定的參考價值,需要的朋友們下面隨著小編來一起學習吧!
問題描述
我希望匹配用三個"
引號括起來的字符串,這些字符串可能包含換行符,并且除開頭和結尾外不包含任何"""
子字符串。
有效示例:
"""foo
bar "baz" blah"""
無效示例:
"""foo bar """ baz"""
我嘗試使用以下正則表達式(作為JavaString
文本):
"(?m)"""(?:[^"]|(?:"[^"])|(?:""[^"]))*""""
而且它似乎在簡短的例子中起作用。但是,在較長的示例中,比如包含1000行hello world
的字符串,它會給我一個StackOverflowError
。
復制錯誤的Scala代碼段
import java.util.regex.{Pattern, Matcher}
val text = """ * 3 + "hello world
" * 1000 + """ * 3
val p = Pattern.compile("(?m)"""(?:[^"]|(?:"[^"])|(?:""[^"]))*"""")
println(p.matcher("""" foo bar baz
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
");
}
bldr.append(""""");
String text = bldr.toString();
Pattern p = Pattern.compile("(?m)"""(?:[^"]|(?:"[^"])|(?:""[^"]))*"""");
System.out.println(p.matcher("""" foo bar baz
baz bar foo """").lookingAt());
System.out.println(p.matcher(text).lookingAt());
}
}
問題
您知道如何使此”堆棧安全”嗎?即,是否有人可以找到接受相同語言,但在提供給Java regex API時不會生成StackOverflowError
的正則表達式?
我不在乎解決方案是使用Scala還是Java(或其他任何語言),只要使用相同的底層Java regex庫即可。
推薦答案
解決方案使用負向前瞻基本上查找以"""
開頭、"""
結尾且不包含"""
內容的字符串
作為普通正則表達式:^"""((?!""")[sS])*"""$
AS Java轉義正則表達式:"^"""((?!""")[\s\S])*"""$
“
sS
包括換行符(基本為.
+換行符或.
帶單行標志)
使用時不應使用MULTLINE標志,以便^
和$
匹配字符串的開始和結束,而不是行的開始和結束
否則:
""" ab
"""abc"""
abc """
將匹配
我還將此作為如何排除"""
:Regular expression to match a line that doesn't contain a word?
的參考
這篇關于多行字符串文字的正則表達式生成`StackOverflow Error`的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,