[英]My regex is causing a stack overflow in Java; what am I missing?
我試圖使用Scanner的正則表達式來匹配文件中的字符串。 正則表達式適用於該行以外的所有內容:
DNA="ITTTAITATIATYAAAYIYI[....]ITYTYITTIYAIAIYIT"
在實際文件中,省略號代表數千個字符。
當讀取文件的循環到達包含基數的行時,會發生堆棧溢出錯誤。
這是循環:
while (scanFile.hasNextLine()) {
final String currentLine = scanFile.findInLine(".*");
System.out.println("trying to match '" + currentLine + "'");
Scanner internalScanner = new Scanner(currentLine);
String matchResult = internalScanner.findInLine(Constants.ANIMAL_INFO_REGEX);
assert matchResult != null : "there's no reason not to find a match";
matches.put(internalScanner.match().group(1), internalScanner.match().group(2));
scanFile.nextLine();
}
和正則表達式:
static final String ANIMAL_INFO_REGEX = "([a-zA-Z]+) *= *\"(([a-zA-Z_.]| |\\.)+)";
這是失敗追蹤:
java.lang.StackOverflowError
at java.util.regex.Pattern$CharProperty.match(Pattern.java:3360)
at java.util.regex.Pattern$Branch.match(Pattern.java:4131)
at java.util.regex.Pattern$GroupHead.match(Pattern.java:4185)
at java.util.regex.Pattern$Loop.match(Pattern.java:4312)
at java.util.regex.Pattern$GroupTail.match(Pattern.java:4244)
at java.util.regex.Pattern$BranchConn.match(Pattern.java:4095)
at java.util.regex.Pattern$CharProperty.match(Pattern.java:3362)
at java.util.regex.Pattern$Branch.match(Pattern.java:4131)
at java.util.regex.Pattern$GroupHead.match(Pattern.java:4185)
at java.util.regex.Pattern$Loop.match(Pattern.java:4312)
at java.util.regex.Pattern$GroupTail.match(Pattern.java:4244)
at java.util.regex.Pattern$BranchConn.match(Pattern.java:4095)
at java.util.regex.Pattern$CharProperty.match(Pattern.java:3362)
at java.util.regex.Pattern$Branch.match(Pattern.java:4131)
at java.util.regex.Pattern$GroupHead.match(Pattern.java:4185)
at java.util.regex.Pattern$Loop.match(Pattern.java:4312)
at java.util.regex.Pattern$GroupTail.match(Pattern.java:4244)
at java.util.regex.Pattern$BranchConn.match(Pattern.java:4095)
...etc (it's all regex).
非常感謝!
這看起來像bug 5050507 。 我同意Asaph的說法,取消交替應該有所幫助; 該bug專門說“盡可能避免交替”。 我想你可能會更簡單:
"^([a-zA-Z]+) *= *\"([^\"]+)"
試試這個正則表達式的簡化版本,刪除一些不必要的|
運算符(可能導致正則表達式引擎執行大量分支)並包括行錨的開始和結束。
static final String ANIMAL_INFO_REGEX = "^([a-zA-Z]+) *= *\"([a-zA-Z_. ]+)\"$";
閱讀本文以了解問題: http : //www.regular-expressions.info/catastrophic.html ...然后使用其他建議之一
正如其他人所說的那樣,你的正則表達式效率遠低於應有的效率。 我會更進一步,使用占有量詞:
"^([a-zA-Z]++) *+= *+\"([^\"]++)\"$"
但是你使用掃描儀的方式也沒有多大意義。 沒有必要使用findInLine(".*")
來讀取該行; 這就是nextLine()
作用。 而且您不需要創建另一個掃描程序來應用您的正則表達式; 只需使用匹配器。
static final Pattern ANIMAL_INFO_PATTERN =
Pattern.compile("^([a-zA-Z]++) *+= *+\"([^\"]++)\"$");
...
Matcher lineMatcher = ANIMAL_INFO_PATTERN.matcher("");
while (scanFile.hasNextLine()) {
String currentLine = scanFile.nextLine();
if (lineMatcher.reset(currentLine).matches()) {
matches.put(lineMatcher.group(1), lineMatcher.group(2));
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.