我使用正則表達式來從任意長度的輸入字符串中提取鍵 - 值對,並運行到其中,對於一個長的字符串具有重複的圖案,它導致堆棧溢出的情況。爪哇模式導致堆棧溢出
的KV-解析代碼看起來是這樣的:
public static void parse(String input)
{
String KV_REGEX = "((?:\"[^\"^ ]*\"|[^=,^ ])*) *= *((?:\"[^\"]*\"|[^=,^\\)^ ])*)";
Pattern KV_PATTERN = Pattern.compile(KV_REGEX);
Matcher matcher = KV_PATTERN.matcher(input);
System.out.println("\nMatcher groups discovered:");
while (matcher.find())
{
System.out.println(matcher.group(1) + ", " + matcher.group(2));
}
}
輸出的一些虛構的例子:
String input1 = "2012-08-09 09:10:25,521 INFO com.a.package.SomeClass - Everything working fine {name=CentOS, family=Linux, category=OS, version=2.6.x}";
String input2 = "2012-08-09 blah blah 09:12:38,462 Log for the main thread, PID=5872, version=\"7.1.8.x\", build=1234567, other=done";
調用parse(input1)
生產:
{name, CentOS
family, Linux
category, OS
version, 2.6.x}
調用parse(input2)
生產:
PID, 5872
version, "7.1.8.x"
build, 1234567
other, done
這是優良(即使是使用用於第一殼體所需要的比特串的處理)。但是,試圖解析很長(超過1000個字符)的類路徑字符串,上述類溢出,但以下情況除外時(啓動):
Exception in thread "main" java.lang.StackOverflowError
at java.util.regex.Pattern$BitClass.isSatisfiedBy(Pattern.java:2927)
at java.util.regex.Pattern$8.isSatisfiedBy(Pattern.java:4783)
at java.util.regex.Pattern$8.isSatisfiedBy(Pattern.java:4783)
at java.util.regex.Pattern$8.isSatisfiedBy(Pattern.java:4783)
at java.util.regex.Pattern$8.isSatisfiedBy(Pattern.java:4783)
at java.util.regex.Pattern$CharProperty.match(Pattern.java:3345)
...
字符串太長,放在這裏,但它具有以下,容易複製和重複結構:
java.class.path=/opt/files/any:/opt/files/any:/opt/files/any:/opt/files/any
誰想要重現該問題只需要幾十次追加:/opt/files/any
上面的字符串。在創建一個包含約90個「:/ opt/files/any」副本的字符串後,會發生堆棧溢出。
有沒有一種通用的方法,上述KV_REGEX
字符串可以修改,這樣就不會出現問題,同樣的結果產生?
我明確提出通用的上面,而不是黑客的是(例如)在解析之前檢查的最大字符串長度。
最總值(GDP)修正我能想出,一個真正的反模式,是
public void safeParse(String input)
{
try
{
parse(input);
}
catch (StackOverflowError e) // Or even Throwable!
{
parse(input.substring(0, MAX_LENGTH));
}
}
有趣的是,它工作在幾個運行我嘗試過,但它是不是足夠有品位的建議。 :-)
祝賀您打破了限制。 – kosa 2012-08-09 20:32:52
謝謝!我會隨時接受獎勵的解決方案! :-)究竟是什麼限制破了? – PNS 2012-08-09 20:36:33
這部分應該匹配什麼?它看起來不正確。 '[^ =,^ \\)^]'。 – Keppil 2012-08-09 20:36:50