1. 程式人生 > 其它 >Java中的正則表示式匹配功能

Java中的正則表示式匹配功能

java語言中的正則表示式匹配功能

java語言中的正則表示式匹配功能主要是通過java.util.regex.Matcher類和以下這些方法實現的。

  • find():在一個字串裡尋找一個給定模式的匹配。
  • lookingAt(): 用一個給定的模式去嘗試匹配一個字串的開頭。
  • matches():用一個給定的模式去嘗試匹配一個完整的字串。
  • replaceAll():進行替換操作,對所有的匹配都進行替換。
  • replaceFirst():進行替換操作,只對第一個匹配進行替換。
    matcher類還提供了幾個能夠讓程式設計師對特定操作做出更細緻調控的方法。此外,java.util.regex.pattern類也提供了幾個簡單易用的包裝器方法。
  • compile():把一個正則表示式編譯成一個模式。
  • flags():返回某給定模式的匹配標誌。
  • matches():在功能上等價於剛才介紹的matches()方法。Pattern類的構造方法是私有的,所以我們使用Pattern p = Pattern.compile("a*b")進行例項化;Matcher類的例項化依賴Pattern類的物件Matcher m = p.matcher("aaaaab");
  • pattern():把一個模式還原為一個正則表示式。
  • split():把一個字串分為子字串。

在實際的開發中,為了方便我們很少直接使用Pattern類或Matcher類,而是使用String類下的方法

  • 驗證:boolean matches(String regex)
  • 拆分: String[] split(String regex)
  • 替換: String replaceAll(String regex, String replacement)

注意事項

Sun公司釋出的Java正則表示式支援與Perl語言基本相容,但要注意以下幾點。

  • 要想使用正則表示式,必須先用import java.util.regex.* 語句匯入正則表示式元件(這條語句將匯入一個完整的軟體包。如果你只需要用到其中的一部分功能,請用相應的軟體包名字替換掉這條語句裡的*)。
  • 不支援嵌入條件。
  • 不支援使用\E、\l、\L、\u和\U進行字母大小寫轉換。
  • 不支援使用\b匹配退格符。
  • 不支援\z。

java中正則表示式常用的語法

字元的取值範圍

  • [abc] : 表示可能是a,可能是b,也可能是c。
  • [^abc]: 表示不是a,b,c中的任意一個
  • [a-zA-Z]: 表示是英文字母
  • [0-9]:表示是數字

簡潔的字元表示

  • .:匹配任意的字元
  • \d:表示數字
  • \D:表示非數字
  • \s:表示由空格組成,[ \t\n\r\x\f]
  • \S:表示由非空字元組成,[^\s]
  • \w:表示字母、數字、下劃線,[a-zA-Z0-9_]
  • \W:表示不是由字母、數字、下劃線組成
  • \b:匹配一個字邊界,即字與空格間的位置。例如,"er\b"匹配"never"中的"er",但不匹配"verb"中的"er"。
  • \B:非字邊界匹配。"er\B"匹配"verb"中的"er",但不匹配"never"中的"er"。

數量表達式

  • ?: 表示出現0次或1次
  • +: 表示出現1次或多次
  • *: 表示出現0次、1次或多次
  • {n}:表示出現n次
  • {n,m}:表示出現n~m次
  • {n,}:表示出現n次或n次以上
  • ?:當此字元緊隨任何其他限定符(*、+、?、{n}、{n,}、{n,m})之後時,匹配模式是"非貪心的"。"非貪心的"模式匹配搜尋到的、儘可能短的字串,而預設的"貪心的"模式匹配搜尋到的、儘可能長的字串。例如,在字串"oooo"中,"o+?"只匹配單個"o",而"o+"匹配所有"o"。

注意:*, +, {n,}都是常用的貪婪型元字元,在匹配時它們會盡可能地從一段文字的開頭一直匹配到這段文字的末尾,而不是從這段文字的開頭匹配到碰到第一個匹配時為止。
例如:
文字:
living in <B>AK</B> and <B>HI</B>.
正則表示式:
<Bb>.*<Bb>
結果:
living in <B>AK</B> and <B>HI</B>.

這時需要使用相應的懶惰型元字元,防止過度匹配,在貪婪型元字元後加上一個?字尾即可,即*?、+?、{n,}?等。
例如:
文字:
living in <B>AK</B> and <B>HI</B>.
正則表示式:
<Bb>.*?<Bb>
結果:
living in <B>AK</B> and <B>HI</B>.

邏輯表示式

  • XY: 表示X後面跟著Y,這裡X和Y分別是正則表示式的一部分
  • X|Y:表示X或Y,比如"food|f"匹配的是foo(d或f),而"(food)|f"匹配的是food或f
  • (X):子表示式,將X看做是一個整體

多用途元字元

  • *:只有當它出現在一個字元集合裡(被放在[和]之間)並緊跟在左方括號[的後面時,它才能發揮“求非”作用。如果是在一個字元集合的外面並位於一個模式的開頭,^將匹配字串的開頭。
    例如:[^abc]: 表示不是a,b,c中的任意一個;
    ^\s*<\?xml.*\?>:匹配一個<?xml>標籤內容,並且該內容出現在字串的開頭
    相應的,$匹配字串的結尾,如\s*$匹配一個字串結尾處的零個或多個空白字元

回溯引用匹配:前後一致匹配

例如:
文字:

<H1>ColdFusion</H1>
<H2>ColdFusion</H2>
<H2>This is not valid HTML</H3>

正則表示式:
<[hH][1-6]>.*?</[hH][1-6]>
結果:
<H1>ColdFusion</H1>
<H2>ColdFusion</H2>
<H2>This is not valid HTML</H3>
分析:
在這個例子裡,原始文本里有一個標題是以<H2>開頭、以<H3>結束的。這顯然是一個不合法的標題,但它與我們所使用的模式匹配上了。出現這種情況的根源是這個模式的第2部分(用來匹配結束標籤的那個部分)對這個模式的第1部分(用來匹配開始標籤的那個部分)毫無所知。要想徹底解決這個問題,就只能求助於回溯引用。
再如:
文字:
This is a block of of text, several words here are are repeated

正則表示式:
[ ]+(\w+)[ ]+\1
結果:
This is a block of of text, several words here are are repeated
分析:
[ ]+匹配一個或多個空格,\w+匹配一個或多個字母數字字元,[ ]+匹配隨後的空格。注意,\w+是括在括號裡的,它是一個子表示式。這個子表示式不是用來進行重複匹配的,這裡根本不涉及重複匹配的問題。這個子表示式只是把整個模式的一部分單獨劃分出來以便在後面引用。這個模式的最後一部分是\1;這是一個回溯引用,而它引用的正是前面劃分出來的那個子表示式:當(\w+)匹配到單詞of的時候,\1也匹配單詞of;當(\w+)匹配到單詞and的時候,\1也匹配單詞and。可以把回溯引用想像成變數
所以,上一個例子的正則表達應該寫成:
<[hH]([1-6])>.*?</[hH]\1>
結果:
<H1>ColdFusion</H1>
<H2>ColdFusion</H2>
<H2>This is not valid HTML</H3>
分析:
<[hH]([1-6])>匹配任何一級標題的開始標籤,但我們這次用(和)把[1-6]括了起來,使它成為了一個子表示式。這樣一來,我們就可以在用來匹配標題結束標籤的</[hH]\1>用\1來引用這個子表示式了。子表示式([1-6])匹配數字1~6, \1只匹配與之相同的數字。這樣一來,原始文本里的<H2>This is notvalid HTML就不會被匹配到了。

轉義字元

在其他語言中,\\ 表示:我想要在正則表示式中插入一個普通的(字面上的)反斜槓,請不要給它任何特殊的意義。

在 Java 中,\\ 表示:我要插入一個正則表示式的反斜線,所以其後的字元具有特殊的意義。

所以,在其他的語言中(如 Perl),一個反斜槓 \ 就足以具有轉義的作用,而在 Java 中正則表示式中則需要有兩個反斜槓才能被解析為其他語言中的轉義作用。也可以簡單的理解在 Java 的正則表示式中,兩個 \\ 代表其他語言中的一個 \,這也就是為什麼表示一位數字的正則表示式是 \\d,而表示一個普通的反斜槓是 \\
() System.out.print("\\"); // 輸出為 \ System.out.print("\\\\"); // 輸出為 \\ ()

瞭解更多請轉到 RUNOOB.COM