1. 程式人生 > >正則表達式Matcher.find報錯 java.lang.StackOverflowError解決

正則表達式Matcher.find報錯 java.lang.StackOverflowError解決

出了 drag 換行符 string 內容 plugins stat 字符 stack

在最近一個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中使用正則表達式時,盡量的匹配少量的內容,就不會出錯了。


正則表達式Matcher.find報錯 java.lang.StackOverflowError解決