JAVA 正則表達式的溢出問題 及不完全解決方案。 (感謝Lancelot 在評論中給出的方法)

          Exception in thread "main" java.lang.StackOverflowError
          at java.lang.Character.codePointAt(Character.java:
          2335)
          at java.util.regex.Pattern$CharProperty.match(Pattern.java:
          3344)
          at java.util.regex.Pattern$Branch.match(Pattern.java:
          4114)
          at java.util.regex.Pattern$GroupHead.match(Pattern.java:
          4168)
          at java.util.regex.Pattern$LazyLoop.match(Pattern.java:
          4357)
          at java.util.regex.Pattern$GroupTail.match(Pattern.java:
          4227)
           at java.util.regex.Pattern$BranchConn.match(Pattern.java:
          4078)
          類似于以上異常,源自于正則匹配需要不斷地遞歸字符串。當字符串遞歸超過800+,具體數字忘記了,就會出現堆棧溢出。
           我在實際應用的場景是,匹配一個網頁尋求《div》《/div》 之間的內容。當div 之間字符達到了950的時候這時候產生了 類似以上的錯誤。
          經過分析,和網友遇到的類似問題貼http://topic.csdn.net/u/20110303/10/6a7dce52-481b-430a-b442-98099e9a01c9.html
          得出以下不完全正確的解析方案

          在正則表達式匹配時對字符個數進行限制 如:"<div>(.*?|\n*|\r*)*</div> 變成了 <div>(.*?|\n*|\r*){0,700}</div> 這樣達到了限制字符的作用。
          但是當解析到此條目時速度仍然非常慢。

          如果您有更好的解決方案請您聯系我。

          歡迎轉帖。轉帖請標注出處,以更好的和大家探討解決問題。

          ——————————————————————————————————————
          Lancelot 提出的正則<div[^>]*>([\s\S]*?)</div>  或<div>([\s\S]*?)</div>
          由于沒有分支條件,因此大大減少了正則匹配過程的回溯深度。因此成功解決了這一問題。
          目前能和大家分享的是,如果遇到類似問題還需簡化正則,減少分支條件等。
          如果您有更好的方案歡迎您提出寶貴的建議。

          posted on 2011-04-28 10:55 scorpio小蝎 閱讀(4890) 評論(12)  編輯  收藏 所屬分類: java

          評論

          # re: JAVA 正則表達式的溢出問題 及不完全解決方案。 2011-04-28 10:59 scorpio小蝎

          如果您有更好的解決方案,和遇到類似的問題請聯系我  回復  更多評論   

          # re: JAVA 正則表達式的溢出問題 及不完全解決方案。 2011-04-28 12:13 Lancelot

          沒見過你說的問題。
          但是你寫的正則實在太菜了,至少你的正則應該寫成下面這樣吧???
          <div[^>]*>([\s\S]*?)</div>  回復  更多評論   

          # re: JAVA 正則表達式的溢出問題 及不完全解決方案。 2011-04-28 12:18 Lancelot

          簡單分析了一下你的正則,你寫的正則回朔次數太多,估計是這個原因才導致的堆溢出。  回復  更多評論   

          # re: JAVA 正則表達式的溢出問題 及不完全解決方案。 2011-04-28 12:39 Peace

          (?s)<div>(.*?)</div>
          注:(?s)表示.匹配任意字符,包含回車,見 : http://fireinwind.iteye.com/blog/724978  回復  更多評論   

          # re: JAVA 正則表達式的溢出問題 及不完全解決方案。 2011-04-28 13:59 Lancelot

          @Peace
          你說的這個"(?s)"是符合NFA引擎還是符合DFA引擎的???
          拜托不要用方言好不好,這樣通用性也太差了吧???
          還有,你以為"(.*?)"能匹配換行符???

          答疑解惑是好的,但是你也總不能用不規范,甚至是錯誤的東西來誤導人家吧。  回復  更多評論   

          # re: JAVA 正則表達式的溢出問題 及不完全解決方案。 2011-04-28 14:04 scorpio小蝎

          @scorpio小蝎
          非常感謝您的回復,我也參考了一些網上的資料。像您說的一樣,是回溯太多的問題。那么怎樣寫正則能減少一些回溯呢?提高正則的效率。您能給我一些相關資料,或者參考不  回復  更多評論   

          # re: JAVA 正則表達式的溢出問題 及不完全解決方案。 2011-04-28 14:04 scorpio小蝎

          @Peace
          謝謝您的回復  回復  更多評論   

          # re: JAVA 正則表達式的溢出問題 及不完全解決方案。 2011-04-28 14:49 Lancelot

          給一個你的數據標本。
          高效的正則是需要量身定做的。
          還有就是你可以用我之前發的正則試試,比你正則的回朔次數要少。  回復  更多評論   

          # re: JAVA 正則表達式的溢出問題 及不完全解決方案。 2011-04-28 14:55 scorpio小蝎

          @Lancelot
          數據標本沒有看到,可能是沒法過來。 發我郵箱吧,謝謝。roymoro@gmail.com
          另外我想知道您是如何分析回溯次數的。我想是否可以通過某種方法來限定回溯深度呢。
          對于您的這個正則,我的div 比較特殊 并沒有 屬性字段(是否可以去掉[^>]*) , 您說的對深度的影響是不主要產生在或的分隔符產生的代價呢
          <div[^>]*>([\s\S]*?)</div>
            回復  更多評論   

          # re: JAVA 正則表達式的溢出問題 及不完全解決方案。 2011-04-28 15:06 scorpio小蝎

          @Lancelot
          直接解決了問題,非常感謝。
          雖然這次是由于正則寫的很菜的原因,但就與這次的問題,我想繼續研究一下 正則 的 匹配機制,和如何才能寫出高效的正則。 想請您給些這方面的建議和參考資料。 比如在這次就發現了,回溯到一定情況下會 發出異常這個嚴重的問題,基本上是由于 | 的分支太多,導致了回溯量的暴增  回復  更多評論   

          # re: JAVA 正則表達式的溢出問題 及不完全解決方案。 2011-04-28 15:09 Lancelot

          @scorpio小蝎
          剛才我的表述方式會引起歧義,我的本意是說:你應該把你需要處理的數據放一個標本出來。
          "[^>]*"只是為了匹配div標簽里的attribute的,如果沒有,去掉就是了,如不去掉,每次匹配的時候會多增加一次回朔。
          關于,回朔次數分析,你應該先去了解正則匹配的機制——正則是一個一個字符匹配的。你寫的正則,會根據行數的不同,有不同的回朔次數,我寫的正則,只會有950(對應:"當div 之間字符達到了950的時候這時候產生了 類似以上的錯誤")次回朔。  回復  更多評論   

          # re: JAVA 正則表達式的溢出問題 及不完全解決方案。 (感謝Lancelot 在評論中給出的方法) 2011-04-28 15:14 scorpio小蝎

          @Lancelot
          了解了,非常感謝。以后有問題向您請教  回復  更多評論   

          <2011年4月>
          272829303112
          3456789
          10111213141516
          17181920212223
          24252627282930
          1234567

          導航

          統計

          常用鏈接

          留言簿

          隨筆分類

          隨筆檔案

          友情鏈接

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 湟源县| 宁国市| 读书| 安阳县| 南召县| 亳州市| 波密县| 本溪市| 高邮市| 大竹县| 肃南| 南皮县| 耒阳市| 定安县| 翁源县| 阳山县| 揭西县| 全椒县| 荥经县| 丰宁| 岑溪市| 建德市| 淄博市| 秦皇岛市| 拉孜县| 青岛市| 永昌县| 宁明县| 门源| 安陆市| 图片| 无锡市| 商丘市| 织金县| 砚山县| 清河县| 双鸭山市| 德江县| 岑巩县| 镇安县| 桃园市|