欧美三区_成人在线免费观看视频_欧美极品少妇xxxxⅹ免费视频_a级毛片免费播放_鲁一鲁中文字幕久久_亚洲一级特黄

Java 正則表達式全攻略(二)

系統 3435 0

Java 正則表達式全攻略(二)

[ 2010-04-23 12:43:42.0 | 作者: 隨想 類別: 基礎強化 ] 來源: 網絡收集 ??? 瀏覽 1512
labels:Java 正則表達式全攻略(二) java正則表達式 字符集

正則表達式引擎的內部工作機制

知道正則表達式引擎是如何工作的,將有助于你很快理解為何某個正則表達式不像你期望的那樣工作,還可以 使你清楚如何對表達式進行性能優化。從最基本的正則表達式引擎實現思路上來分的話,有兩種:確定型有限狀態機(Deterministic Finite-State Automaton)簡稱DFA和不確定型有限狀態機(Nodeterministic Finite-State Automaton)簡稱NFA,也有人稱其為文本導向和正則導向。以下這個網址 http://osteele.com/tools/reanimator/ 以一種非常直觀的方式說明了 DFA 和 NFA 對相同的表達式的不同編譯結果。

由于我們的目的不在于學習狀態機,所以我們忽略這2者的工作原理,直接對比他們的影響。就拿表達式 a|ab|abc|abcd 來對比。 我們可以看到NFA的結果比較復雜,而DFA十分簡潔,這是否又會影響到2者的性能呢?確實如此,DFA的執行速度與表達式無關,它在編譯時的優化已經優 于大多數 NFA引擎的復雜優化措施。而NFA的執行速度與表達式有著直接的關系。從匹配結果來看,DFA總是返回最左邊最長的匹配結果,而NFA總是比較猴急,總 會匹配第一個找到的結果。根據這一點,我們可以輕易分辨出所使用的引擎是DFA還是NFA,你可以使用表達式 nfa|nfa not 對字符串”nfa not”進行測試,如果匹配結果是 nfa ,那該引擎是NFA的,而Java就是屬于NFA的。最后一點就是,NFA能提供的功能比DFA更多,例如:捕獲由括號內的子表達式匹配的文本、環視,以 及其他復雜的零長度確認、“惰性”量詞等。而我們講的是Java的正則表達式,那當然也就是在說NFA啦,而NFA由于功能比較多用起來比較方便,因此比 DFA要流行些。

正則導向的引擎總是返回最左邊的匹配

這是需要你理解的很重要的一點:即使以后有可能發現一個“更好”的匹配,正則導向的引擎也總是返回最左邊的匹配。 當把 cat 應用到“He captured a catfish for his cat”,引擎先比較 c 和“H”,結果失敗了。于是引擎再比較 c 和“e”,也失敗了。直到第四個字符, c 匹配了“c”。 a 匹配了第五個字符。到第六個字符 t 沒能匹配“p”,也失敗了。引擎再繼續從第五個字符重新檢查匹配性。直到第十五個字符開始, cat 匹配上了“catfish”中的“cat”,正則表達式引擎急切的返回第一個匹配的結果,而不會再繼續查找是否有其他更好的匹配。

字符集

字符集是由一對方括號“[]”括起來的字符集合。使用字符集,你可以告訴正則表達式引擎僅僅匹配多個字符中的一個。如果你想匹配一個“a”或一個“e”,使用 [ae] 。你可以使用 gr[ae]y 匹配gray或grey。這在你不確定你要搜索的字符是采用美國英語還是英國英語時特別有用。相反, gr[ae]y 將不會匹配graay或graey。字符集中的字符順序并沒有什么關系,結果都是相同的。

你可以使用連字符“-”定義一個字符范圍作為字符集。 [0-9] 匹配0到9之間的單個數字。你可以使用不止一個范圍。 [0-9a-fA-F] 匹配單個的十六進制數字,并且大小寫不敏感。你也可以結合范圍定義與單個字符定義。 [0-9a-fxA-FX] 匹配一個十六進制數字或字母X。再次強調一下,字符和范圍定義的先后順序對結果沒有影響。

取反字符集

在左方括號“[”后面緊跟一個尖括號“^”,將會對字符集取反。結果是字符集將匹配任何不在方括號中的字符。不像“.”,取反字符集是可以匹配回車換行符的。

需要記住的很重要的一點是,取反字符集必須要匹配一個字符。 q[^u] 并不意味著:匹配一個q,后面沒有u跟著。它意味著:匹配一個q,后面跟著一個不是u的字符。所以它不會匹配“Iraq”中的q,而會匹配“Iraq is a country”中的q和一個空格符。事實上,空格符是匹配中的一部分,因為它是一個“不是u的字符”。如果你只想匹配一個q,條件是q后面有一個不是u 的字符,我們可以用后面將講到的向前查看來解決。

字符集中的元字符

需要注意的是,在字符集中只有4個 字符具有特殊含義。它們是:“ ] \ ^ - ”。“]”代表字符集定義的結束;“\”代表轉義;“^”代表取反;“-”代表范圍定義。其他常見的元字符在字符集定義內部都是正常字符,不需要轉義。例如,要搜索星號*或加號+,你可以用 [+*] 。當然,如果你對那些通常的元字符進行轉義,你的正則表達式一樣會工作得很好,但是這會降低可讀性。

在字符集定義中為了將反斜杠“\”作為一個文字字符而非特殊含義的字符,你需要用另一個反斜杠對它進行轉義。 [\\x] 將會匹配一個反斜杠和一個X。“]^-”都可以用反斜杠進行轉義,或者將他們放在一個不可能使用到他們特殊含義的位置。我們推薦后者,因為這樣可以增加可讀性。比如對于字符“^”,將它放在除了左括號“[”后面的位置,使用的都是文字字符含義而非取反含義。如 [x^] 會匹配一個x或^。 []x] 會匹配一個“]”或“x”。 [-x] [x-] 都會匹配一個“-”或“x”。

字符集的簡寫

因為一些字符集非常常用,所以有一些簡寫方式。

. 任何字符(與行結束符可能匹配也可能不匹配)
\d 數字: [0-9]
\D 非數字: [^0-9]
\s 空白字符: [\t\n\x0b\f\r]
\S 非空白字符: [^\s]
\w 單詞字符: [a-zA-Z_0-9]
\W 非單詞字符: [^\w]


字符集的重復

如果你用“ ?*+ ”操作符來重復一個字符集,你將會重復整個字符集。而不僅是它匹配的那個字符。正則表達式 [0-9]+ 會匹配837以及222。如果你僅僅想重復被匹配的那個字符,可以用向后引用達到目的。我們以后將講到向后引用。

* 重復零次或更多次
+ 重復一次或更多次
? 重復零次或一次
{n} 重復n次
{n,} 重復n次到更多次
{n,m} 重復n到m次

結合前面的知識,我們就可以寫出以下這類常用的表達式:

        
          
            
               1:
            
          
        
        
          
            
              // 判斷字符串是否一個合法的16進制
            
          
        
      
        
          
            
               2:
            
          
        
        
          
             String regex = 
            
              "[-+]?0[xX]?[0-9a-fA-F]+"
            
             ;
          
        
      
        
          
            
               3:
            
          
        
        
          
             System.out.println(
            
              "0xFF"
            
             .matches(regex)); 
            
              // true
            
          
        
      
        
          
            
               4:
            
          
        
        
          
             System.out.println(
            
              "-0Xff"
            
             .matches(regex)); 
            
              // true
            
          
        
      
        
          
            
               5:
            
          
        
        
          
             System.out.println(
            
              "ff"
            
             .matches(regex)); 
            
              // false
            
          
        
      
        
          
            
               6:
            
          
        
        
          
             System.out.println(
            
              "0x1H"
            
             .matches(regex)); 
            
              // false
            
          
        
      
        
          
            
               7:
            
          
        
        
          
            
              // 簡單地判斷一個字符串是否合法的身份證號碼
            
          
        
      
        
          
            
               8:
            
          
        
        
          
             regex = 
            
              "\\d{15}|\\d{18}"
            
             ;
          
        
      
        
          
            
               9:
            
          
        
        
          
             System.out.println(
            
              "440104700101001"
            
             .matches(regex)); 
            
              // ture;
            
          
        
      
        
          
            
               10:
            
          
        
        
          
             System.out.println(
            
              "44010700101001"
            
             .matches(regex)); 
            
              // false;
            
          
        
      
        
          
            
               11:
            
          
        
        
          
             System.out.println(
            
              "440104197001010015"
            
             .matches(regex)); 
            
              // ture;
            
          
        
      
        
          
            
               12:
            
          
        
        
          
             System.out.println(
            
              "4401041970010100015"
            
             .matches(regex));
            
              // false;
            
          
        
      

Java 正則表達式全攻略(二)


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 日韩亚洲欧美视频 | 亚洲一区在线观看视频 | 久草色在线 | 亚洲午夜精品视频 | 亚洲精品国产综合一线久久 | 亚洲精品午夜视频 | 99热最新网址 | 精品国产福利在线 | 国产黄色一级毛片 | 宝贝jojo第三季 | 欧美激情精品久久久久久变态 | 国产午夜精品一区二区三区嫩草 | 国内自拍一二三四2021 | 午夜色大片在线观看 | 国产欧美一区二区三区另类精品 | 亚洲国产综合精品中文第一区 | 毛片成人永久免费视频 | 亚洲福利一区福利三区 | 成人在线免费看 | 国产精品v在线播放观看 | 国产++欧洲韩国野花视频 | 色呦呦免费观看 | 国产精品国产a | jjzzjjzz在线观看 | 欧美爽爽爽爽爽爽视频 | 亚洲狠狠丁香婷婷综合久久久 | 亚洲欧美综合人成野草 | 国产精品久久久久无毒 | 一区二区三区四区国产精品视频 | 奇米影视8888| 99riav在线| 成人在线日韩 | 免费大香伊蕉在人线国产 | 天天色天天综合 | 精品亚洲国产成av人片传媒 | 欧美激情视频网站 | 国产精品久久久久久久久免费 | 日韩成人免费av | 国产精品乱码在线观看 | 久久综合九九 | 精品国产乱码久久久久久久 |