天天看點

Java與正規表達式 Java與正規表達式

标簽: Java基礎

正如<code>正則</code>的名字所顯示的是描述了一個<code>規則</code>, 通過這個規則去<code>比對字元串</code>. 學習正則就是學習正規表達式的<code>文法規則</code>

字母, 數字, 漢字, 下劃線, 以及沒有特殊定義的标點符号都是<code>普通字元</code>. 表達式中的普通字元在比對一個字元串時, 比對與之相同的一個字元.

字元

解釋

<code>\n</code>

換行符

<code>\t</code>

制表符

<code>\^</code> <code>\$</code> <code>\(</code> <code>\)</code> <code>\{</code> <code>\}</code> <code>\?</code> <code>\+</code> <code>\*</code> <code>|</code> <code>\\</code> <code>\[</code> <code>\]</code>

比對這些字元本身

比對

<code>\d</code>

任意一個數字

<code>\w</code>

任意一個字母/數字/下劃線

<code>\s</code>

任意一個空格/制表符/換行符等空白字元

<code>.</code>

小數點在内的任意一個字元(除<code>\n</code>外)

<code>[\s\S]</code>

比對<code>\n</code>在内的任意一個字元

注意大小寫: 大寫是取反

<code>[]</code> 方括号比對方式, 能夠比對方括号中的任意一個字元.

表達式

<code>[ab5@v]</code>

比對<code>a</code> <code>b</code> <code>5</code> <code>@</code> <code>v</code>中任意一個

<code>[^ab5@v]</code>

比對<code>a</code> <code>b</code> <code>5</code> <code>@</code> <code>v</code>之外任意一個

<code>[f-k]</code>

比對<code>f-k</code>之間任意一個字母

<code>[^f-k]</code>

比對<code>f-k</code>之外任意一個

<code>[f-k0-3]</code>

比對<code>f-k</code>或<code>0-3</code>之間任意一個字母

<code>[^f-k0-3]</code>

不比對<code>f-k</code>或<code>0-3</code>之間任意一個字母

注:

正規表達式中的特殊符号, 被包含到<code>[]</code>中, 則失去特殊意義, 除了<code>-</code> <code>^</code>之外.

<code>[]</code>中的<code>^</code>表示取反的含義.

<code>[]</code>中的<code>-</code>表示範圍的含義

标準字元集合(除小數點外),如果被包含于中括号中,則自定義集合将包含該集合.

如<code>[\d.\-+]</code>将比對: 數字, 小數點, <code>-</code>, <code>+</code>

量詞

<code>{n}</code>

表達式重複n次

<code>{m,n}</code>

表達式至少重複m次,最多重複n次

<code>{m,}</code>

表達式至少重複m次

<code>?</code>

比對表達式0次或者1次

<code>+</code>

表達式至少出現1次,相當于 <code>{1,}</code>

<code>*</code>

表達式不出現或出現任意次,相當于 <code>{0,}</code>

貪婪模式與非貪婪模式

貪婪模式: 比對字元越多越好, <code>預設</code>.

非貪婪模式: 比對字元越少越好, 需要在量詞後再加上一個<code>?</code>号.

示例

比對手機号<code>1[358]\d{9}</code>

比對郵箱 <code>([\w\-\.]+)@([0-9a-zA-Z\-]+)(\.[a-zA-Z]{2,4}){1,2}</code>

零寬比對: 比對的不是字元而是位置(符合某種條件的位置),不比對任何字元.

<code>^</code>

與字元串開始的地方比對

<code>$</code>

與字元串結束的地方比對

<code>\b</code>

比對一個單詞邊界,也就是單詞和空格之間的位置

注: <code>\b</code>會比對這樣一個位置: 前面的字元與後面的字元不全是<code>\w</code>

<code>|</code>

左右兩邊表達式之間 “或” 關系,比對左邊或右邊

<code>()</code> 捕獲組

被修飾時,<code>()</code>中的表達式可以作為整體被修飾; 取比對結果時, <code>()</code>中的表達式比對到的内容可以被單獨得到; 每一對括号會被配置設定一個編号(以<code>(</code>為準,從左到右: 從1開始)

<code>(?:exp)</code> 非捕獲組

一些表達式中, 不得不使用<code>()</code>, 但又不需儲存<code>()</code>中子表達式比對的内容, 這時可以使用非捕獲組來抵消<code>()</code>帶來的副作用

注: 非捕獲組可以用于當處理大量文本時用于優化記憶體配置設定.

反引用<code>\nnn</code>

由上面可知, 捕獲組預設被配置設定了編号, 通過反向引用, 可以對分組已捕獲的字元串進行引用

<code>(\w{2})\1</code> 比對類似<code>toto</code> <code>dodo</code> <code>gogo</code>這樣由一個單詞複制而來得到的字元串

<code>(img)\w+\1</code> 比對前後都是img的字元串

零寬度: 隻進行子表達式的比對, 比對内容不計入最終的比對結果.

位置比對: 判斷目前位置的前後字元是否符合指定的條件, 但不保留前後的字元.

正規表達式中, 如果子表達式比對到得是字元内容, 而非位置, 并被保留到最終的比對結果中, 那麼就認為這個子表達式是<code>占有字元</code>的; 如果子表達式比對的僅僅是位置, 或者比對的内容并不儲存到最終的比對結果中, 那麼就認為這個子表達式是<code>零寬度</code>的(占有字元或零寬度, 是針對比對的内容是否保留到最終結果而言的)

<code>(?=exp)</code>

斷言自身出現的位置的<code>後面能夠</code>比對表達式exp

<code>(?!exp)</code>

斷言自身出現的位置的<code>後面不能</code>比對表達式exp

<code>(?&lt;=exp)</code>

斷言自身出現的位置的<code>前面能夠</code>比對表達式exp

<code>(?&lt;\!exp)</code>

斷言自身出現的位置的<code>前面不能</code>比對表達式exp

<code>[a-z]+(?=ing)</code> 比對所有以ing結尾的單詞, 但ing并不放入字元串

<code>[a-z]+(?=\d+)</code> 比對所有以數字結尾的單詞

<code>[a-z]+(?!\d+)</code> 比對不以數字結尾的單詞

<code>(?&lt;=(href=\"))</code> 比對以<code>href="</code>開頭的字元串

<code>java.util.regex</code>包下提供的<code>Pattern</code>與<code>Matcher</code>兩個類提供了在Java中的正則支援;

<code>Pattern</code>對象是正規表達式編譯後在記憶體中的表現形式, 是以, 正規表達式字元串必須先被編譯為Pattern對象<code>Pattern pattern = Pattern.compile("\\w+");</code>然後再利用該Pattern對象建立對象的Matcher對象<code>Matcher matcher = pattern.matcher(input);</code>.

<code>Matcher</code>對象是一個對<code>CharSequence</code>執行比對操作的正則引擎: 執行比對所涉及的狀态保留在Matcher對象中, 多個Matcher對象可共享同一個Pattern對象.

附- 運作上程式需要在pom.xml中添加以下依賴

推薦幾個正則驗證工具:

參考

<a href="http://www.blogjava.net/19851985lili/articles/97621.html">揭開正規表達式的神秘面紗</a>

<a href="http://www.java3z.com/cwbwebhome/article/article8/Regex/Java.Regex.Tutorial.html#reg8">Java正規表達式教程</a>