在最近一個java項目中使用了正則表達式,抓取網頁中的內容,明明很正確的正則表達式,但在Matcher.find時報錯了:
public static List<String> findStrs(String regx,String sourceStr){
Pattern pattern = Pattern.compile(regx);
Matcher m = pattern.matcher(sourceStr);
List<String> result=new ArrayList<>();
while (m.find()) {
result.add(m.group(1));
} return result.size()<=0?null:result;
}
后來單步調試,發現在第一次find時正確獲取到,第二次報錯了,錯誤是:
java.lang.StackOverflowError
at java.lang.String.charAt(String.java:657)
at java.util.regex.Pattern$Slice.match(Pattern.java:3971)
at java.util.regex.Pattern$LazyLoop.match(Pattern.java:4845)
at java.util.regex.Pattern$GroupTail.match(Pattern.java:4719)
at java.util.regex.Pattern$BranchConn.match(Pattern.java:4570)
at java.util.regex.Pattern$CharProperty.match(Pattern.java:3779)
at java.util.regex.Pattern$Branch.match(Pattern.java:4606)
at java.util.regex.Pattern$GroupHead.match(Pattern.java:4660)
at java.util.regex.Pattern$LazyLoop.match(Pattern.java:4849)
at java.util.regex.Pattern$GroupTail.match(Pattern.java:4719)
at java.util.regex.Pattern$BranchConn.match(Pattern.java:4570)
at java.util.regex.Pattern$CharProperty.match(Pattern.java:3779)
at java.util.regex.Pattern$Branch.match(Pattern.java:4606)
at java.util.regex.Pattern$GroupHead.match(Pattern.java:4660)
at java.util.regex.Pattern$LazyLoop.match(Pattern.java:4849)
at java.util.regex.Pattern$GroupTail.match(Pattern.java:4719)
at java.util.regex.Pattern$BranchConn.match(Pattern.java:4570)
at java.util.regex.Pattern$CharProperty.match(Pattern.java:3779)
at java.util.regex.Pattern$Branch.match(Pattern.java:4606)
at java.util.regex.Pattern$GroupHead.match(Pattern.java:4660)
at java.util.regex.Pattern$LazyLoop.match(Pattern.java:4849)
at java.util.regex.Pattern$GroupTail.match(Pattern.java:4719)
at java.util.regex.Pattern$BranchConn.match(Pattern.java:4570)
at java.util.regex.Pattern$CharProperty.match(Pattern.java:3779)
at java.util.regex.Pattern$Branch.match(Pattern.java:4606)
at java.util.regex.Pattern$GroupHead.match(Pattern.java:4660)
at java.util.regex.Pattern$LazyLoop.match(Pattern.java:4849)
at java.util.regex.Pattern$GroupTail.match(Pattern.java:4719)
at java.util.regex.Pattern$BranchConn.match(Pattern.java:4570)
at java.util.regex.Pattern$CharProperty.match(Pattern.java:3779)
at java.util.regex.Pattern$Branch.match(Pattern.java:4606)
at java.util.regex.Pattern$GroupHead.match(Pattern.java:4660)
at java.util.regex.Pattern$LazyLoop.match(Pattern.java:4849)
... ...
在網上查了下,發現問題是棧溢出,有人給出了解決方法:
Pattern pattern = Pattern.compile(re,Pattern.DOTALL + Pattern.MULTILINE);
其中Pattern.DOTALL + Pattern.MULTILINE指,在正則表達式中的:.可以代替所有字符,包括換行符\n。原先的寫法可能是:xxx(?:\n|.)*?xxx,現在可以寫成xxx.*?xxx,。
使用這個方法,問題暫時解決。但問題原理 不明,可能是sdk的bug吧。
注:此方法可以避免此問題,但附帶的,因為在使用.時,忽略了換行,可能使用正則表達式匹配到更大范圍的內容,所以寫正則時需要格外小心。另外,后來我試了一下,只要在匹配時少於二個換行的內容,不使用此方法,也可以正常運行,所以感覺在java中使用正則表達式時,盡量的匹配少量的內容,就不會出錯了。