JavaSE-31 JavaRegex

來源:互聯網
上載者:User

標籤:pre   ever   compile   聲明   線程   find   efi   相同   目標   

概述

Regex是一個強大的字串處理工具,可以實現對字串的尋找、提取、分割、替換等操作。

String類的幾個方法需要依賴Regex的支援。

方法 方法說明
boolean matches(String regex) 判斷該字串是否匹配指定的Regex
String replaceAll(String regex,String replacement) 將該字串中所有匹配regex的子字串替換成replacement
String replaceFirst(String regex,String replacement) 將該字串中第一個匹配regex的子字串替換成replacement
String[] split(String regex) 以regex作為分隔字元,把該字串分割成多個子字串

Java提供了Pattern和Matcher類支援Regex。

 

建立Regex

Regex文法構成

字元

說明

\

將下一字元標記為特殊字元、文本、反向引用或八進位轉義符。例如,"n"匹配字元"n"。"\n"匹配分行符號。序列"\\\\"匹配"\\","\\("匹配"("。

^

匹配輸入字串開始的位置。如果設定了 RegExp 對象的 Multiline 屬性,^ 還會與"\n"或"\r"之後的位置匹配。

$

匹配輸入字串結尾的位置。如果設定了 RegExp 對象的 Multiline 屬性,$ 還會與"\n"或"\r"之前的位置匹配。

*

零次或多次匹配前面的字元或子運算式。例如,zo* 匹配"z"和"zoo"。* 等效於 {0,}。

+

一次或多次匹配前面的字元或子運算式。例如,"zo+"與"zo"和"zoo"匹配,但與"z"不匹配。+ 等效於 {1,}。

?

零次或一次匹配前面的字元或子運算式。例如,"do(es)?"匹配"do"或"does"中的"do"。? 等效於 {0,1}。

{n}

是非負整數。正好匹配 n 次。例如,"o{2}"與"Bob"中的"o"不匹配,但與"food"中的兩個"o"匹配。

{n,}

是非負整數。至少匹配 次。例如,"o{2,}"不匹配"Bob"中的"o",而匹配"foooood"中的所有 o。"o{1,}"等效於"o+"。"o{0,}"等效於"o*"。

{n,m}

M 和 n 是非負整數,其中 n <= m。匹配至少 n 次,至多 m 次。例如,"o{1,3}"匹配"fooooood"中的頭三個 o。‘o{0,1}‘ 等效於 ‘o?‘。注意:您不能將空格插入逗號和數字之間。

?

當此字元緊隨任何其他限定符(*、+、?、{n}、{n,}、{n,m})之後時,匹配模式是"非貪心的"。"非貪心的"模式比對搜尋到的、儘可能短的字串,而預設的"貪心的"模式比對搜尋到的、儘可能長的字串。例如,在字串"oooo"中,"o+?"只匹配單個"o",而"o+"匹配所有"o"。

.

匹配除"\r\n"之外的任何單個字元。若要匹配包括"\r\n"在內的任一字元,請使用諸如"[\s\S]"之類的模式。

(pattern)

匹配 pattern 並捕獲該匹配的子運算式。可以使用 $0…$9 屬性從結果"匹配"集合中檢索捕獲的匹配。若要匹配括弧字元 ( ),請使用"\("或者"\)"。

(?:pattern)

匹配 pattern 但不捕獲該匹配的子運算式,即它是一個非捕獲匹配,不儲存供以後使用的匹配。這對於用"or"字元 (|) 組合模式組件的情況很有用。例如,‘industr(?:y|ies) 是比 ‘industry|industries‘ 更經濟的運算式。

(?=pattern)

執行正向預測先行搜尋的子運算式,該運算式匹配處於匹配 pattern 的字串的起始點的字串。它是一個非捕獲匹配,即不能捕獲供以後使用的匹配。例如,‘Windows (?=95|98|NT|2000)‘ 匹配"Windows 2000"中的"Windows",但不匹配"Windows 3.1"中的"Windows"。預測先行不佔用字元,即發生匹配後,下一匹配的搜尋緊隨上一匹配之後,而不是在組成預測先行的字元後。

(?!pattern)

執行反向預測先行搜尋的子運算式,該運算式匹配不處於匹配 pattern 的字串的起始點的搜尋字串。它是一個非捕獲匹配,即不能捕獲供以後使用的匹配。例如,‘Windows (?!95|98|NT|2000)‘ 匹配"Windows 3.1"中的 "Windows",但不匹配"Windows 2000"中的"Windows"。預測先行不佔用字元,即發生匹配後,下一匹配的搜尋緊隨上一匹配之後,而不是在組成預測先行的字元後。

x|y

匹配 x 或 y。例如,‘z|food‘ 匹配"z"或"food"。‘(z|f)ood‘ 匹配"zood"或"food"。

[xyz]

字元集。匹配包含的任一字元。例如,"[abc]"匹配"plain"中的"a"。

[^xyz]

反向字元集。匹配未包含的任何字元。例如,"[^abc]"匹配"plain"中"p","l","i","n"。

[a-z]

字元範圍。匹配指定範圍內的任何字元。例如,"[a-z]"匹配"a"到"z"範圍內的任何小寫字母。

[^a-z]

反向範圍字元。匹配不在指定的範圍內的任何字元。例如,"[^a-z]"匹配任何不在"a"到"z"範圍內的任何字元。

\b

匹配一個字邊界,即字與空格間的位置。例如,"er\b"匹配"never"中的"er",但不匹配"verb"中的"er"。

\B

非字邊界匹配。"er\B"匹配"verb"中的"er",但不匹配"never"中的"er"。

\cx

匹配 x 指示的控制字元。例如,\cM 匹配 Control-M 或斷行符號符。x 的值必須在 A-Z 或 a-z 之間。如果不是這樣,則假定 c 就是"c"字元本身。

\d

數字字元匹配。等效於 [0-9]。

\D

非數字字元匹配。等效於 [^0-9]。

\f

換頁符匹配。等效於 \x0c 和 \cL。

\n

分行符號匹配。等效於 \x0a 和 \cJ。

\r

匹配一個斷行符號符。等效於 \x0d 和 \cM。

\s

匹配任何空白字元,包括空格、定位字元、換頁符等。與 [ \f\n\r\t\v] 等效。

\S

匹配任何非空白字元。與 [^ \f\n\r\t\v] 等效。

\t

定位字元匹配。與 \x09 和 \cI 等效。

\v

垂直定位字元匹配。與 \x0b 和 \cK 等效。

\w

匹配任何字類字元,包括底線。與"[A-Za-z0-9_]"等效。

\W

與任何非單詞字元匹配。與"[^A-Za-z0-9_]"等效。

\xn

匹配 n,此處的 n 是一個十六進位轉義碼。十六進位轉義碼必須正好是兩位元長。例如,"\x41"匹配"A"。"\x041"與"\x04"&"1"等效。允許在Regex中使用 ASCII 代碼。

\num

匹配 num,此處的 num 是一個正整數。到捕獲匹配的反向引用。例如,"(.)\1"匹配兩個連續的相同字元。

\n

標識一個八進位轉義碼或反向引用。如果 \n 前面至少有 n 個捕獲子運算式,那麼 n 是反向引用。否則,如果 n 是八位元 (0-7),那麼 n 是八進位轉義碼。

\nm

標識一個八進位轉義碼或反向引用。如果 \nm 前面至少有 nm 個捕獲子運算式,那麼 nm 是反向引用。如果 \nm 前面至少有 n 個捕獲,則 n 是反向引用,後面跟有字元 m。如果兩種前面的情況都不存在,則 \nm 匹配八進位值 nm,其中 和 m 是八位元字 (0-7)。

\nml

當 n 是八位元 (0-3),m 和 l 是八位元 (0-7) 時,匹配八進位轉義碼 nml

\un

匹配 n,其中 n 是以四位十六進位數表示的 Unicode 字元。例如,\u00A9 匹配著作權符號 (?)。

  

數量標識符

如果需要匹配一個郵遞區號,形式如:000-000,使用Regex:\\d\\d\\d-\\d\\d\\d,這種寫法比較繁瑣,可以採用Regex的數量標識符進行簡寫,寫成如下格式:

\\d{3}-\\d{3}

 

Regex中的數量標識符支援三種模式:

  1. Greediness(貪婪模式):Regex中的數量表示預設採用貪婪模式。貪婪模式的運算式會一直匹配下去,直到無法匹配為止。
  2. Reluctant(勉強模式):用問號“?”尾碼表示,他只會匹配最少的字元。也稱為最小匹配模式。
  3. Possessive(佔有模式):尾碼用加號“+”表示,完全符合。較少使用,不是所有程式設計語言都支援。

三種模式數量標識符:

貪婪模式 勉強模式 佔用模式 運算式說明
X? X?? X?+ X運算式出現0次或者1次
X* X*? X*+ X運算式出現0次或者多次
X+ X+? X++ X運算式出現1次或者多次
X{n} X{n}? X{n}+ X表示是出現n次
X{n,} X{n,}? X{n,}+ X運算式最少出現n次
X{n,m} X{n,m}? X{n,m}+ X運算式最少出現n次,最多出現m次

  

  • 貪婪模式樣本

在 Greediness 的模式下,會盡量大範圍的匹配,直到匹配了整個內容,這時發現匹配不能成功時,開始回退縮小匹配範圍,直到匹配成功。

範例程式碼: 

String test="list<a href=‘http://www.baidu.com‘>百度</a>list";String reg="<.+>";//\\.+表示任何字元出現一次或者多次System.out.println(test.replaceAll(reg, "***"));

  說明:我們期望的匹配內容是<a href=‘http://www.baidu.com‘>,但是在貪婪模式下,他會匹配 a href=‘http://www.baidu.com‘>百度</a,結果輸出:

list***list

   

  • 勉強模式樣本

在 Reluctant 的模式下,只要匹配成功,就不再繼續嘗試匹配更大範圍的內容。

範例程式碼: 

String test="list<a href=‘http://www.baidu.com‘>百度</a>list";String reg="<.+?>";//\\.+表示任何字元出現一次或者多次,?表示勉強方式System.out.println(test.replaceAll(reg, "***"));

  輸出結果:

list***百度***list

  

  • 佔用模式樣本 

Possessive 模式與 Greediness 有一定的相似性,那就是都盡量匹配最大範圍的內容,直到內容結束,但與 Greediness 不同的是,完全符合不再回退嘗試匹配更小的範圍。

範例程式碼: 

String test="list<a href=‘http://www.baidu.com‘>百度</a>list";String reg="<.++>";//\\.+表示任何字元出現一次或者多次,+表示佔有方式System.out.println(test.replaceAll(reg, "***"));

  輸出結果:

list<a href=‘http://www.baidu.com‘>百度</a>list

 

常用Regex
規則 Regex文法  
一個或多個漢字 ^[\u0391-\uFFE5]+$ 
郵遞區號 ^[1-9]\d{5}$
QQ號碼 ^[1-9]\d{4,11}$ 
郵箱 ^[a-zA-Z_]{1,}[0-9]{0,}@(([a-zA-z0-9]-*){1,}\.){1,3}[a-zA-z\-]{1,}$ 
使用者名稱(字母開頭 + 數字/字母/底線) ^[A-Za-z][A-Za-z1-9_-]+$
手機號碼 ^1[3|4|5|8][0-9]\d{8}$ 
URL ^((http|https)://)?([\w-]+\.)+[\w-]+(/[\w-./?%&=]*)?$ 
18位社會安全號碼 ^(\d{6})(18|19|20)?(\d{2})([01]\d)([0123]\d)(\d{3})(\d|X|x)?$

 

Regex的使用

Pattern和Matcher類用於處理Regex。處理過程:

  1. Regex字串被編譯為Pattern對象。
  2. 使用Pattern對象建立對應的Matcher對象。
  3. 執行匹配所涉及的狀態保留在Matcher對象中,多個Matcher對象可以共用同一個Pattern對象。

典型應用代碼如下:

//定義Pattern對象:將字串編譯為Pattern對象Pattern p=Pattern.compile("a*b");//使用Pattern對象建立Matcher對象Matcher m=p.matcher("aaaaab");//擷取匹配結果boolean result=m.matches();//輸出匹配結果System.out.println(result);//輸出true

  

Pattern對象可以多次重複使用。如果某個Regex僅需一次使用,可以使用Pattern類的靜態方法matches()。

範例程式碼如下:

boolean b=Pattern.matches("a*b", "aaaab");System.out.println(b);//輸出true

  

  • Pattern類

Pattern對象表示Regex編譯後在記憶體中的表示形式,是不可變類安全執行緒類。

 

  • Matcher類

Matcher類提供了以下常用方法:

方法 說明
find() 返回目標字串中是否包含與Pattern匹配的子字串。
group() 返回上一次與Pattern匹配的子字串。
start() 返回上一次與Pattern匹配的子字串在目標字串中的開始位置。
end() 返回上一次與Pattern匹配的子字串在目標字串中的結束位置+1。
lookingAt() 返回目標字串前面部分與Pattern是否匹配。
matches() 返回整個目標字串與Pattern是否匹配。
reset() 將現有的Matcher對象應用於一個新的字元序列。

 

 

樣本1:使用find()方法和group()方法從目標字串中取出特定子字串。(網路爬蟲提取資訊模型)

//定義目標字串String content="我的電話號碼是13800001234,購買Mac電腦的電話號碼13112340001,拯救單身狗172456789078";//定義提取手機號碼的RegexString reg="((13\\d)|(17\\d))\\d{8}";//定義Pattern對象Pattern p=Pattern.compile(reg);//獲得Matcher對象Matcher m=p.matcher(content);//輸出電話號碼while(m.find()) {System.out.println(m.group());}

  

樣本2:使用find()方法和start()方法、end()方法確定目標字串中特定子字串的位置。

// 定義目標字串String content = "我的電話號碼是13800001234,購買Mac電腦的電話號碼13112340001,拯救單身狗172456789078";// 定義提取手機號碼的RegexString reg = "((13\\d)|(17\\d))\\d{8}";// 定義Pattern對象Pattern p = Pattern.compile(reg);// 獲得Matcher對象Matcher m = p.matcher(content);// 輸出電話號碼while (m.find()) {System.out.println(m.group() + ",該子字串的起始位置:" + m.start() + ",該子字串的結束位置:"+m.end());}

  輸出結果:

13800001234,該子字串的起始位置:7,該子字串的結束位置:1813112340001,該子字串的起始位置:31,該子字串的結束位置:4217245678907,該子字串的起始位置:48,該子字串的結束位置:59

  

樣本3:其他方法的使用。

此外,matches()方法要求整個字串和Pattern完全符合才返回true。

lookingAt()方法只要求字串以Pattern開頭就會返回true。

reset()方法可將現有的Matcher對象應用於新的字串序列。

範例程式碼:

//定義郵箱字串數組String[] mails= {"[email protected]","[email protected]","[email protected]","abc.com"};//郵箱RegexString mailReg="\\w{3,20}@\\w+\\.(com|org|cn|net|gov)";//定義Pattern對象Pattern mp=Pattern.compile(mailReg);//聲明Matcher對象Matcher m=null;for(String mail:mails) {if(m==null) {//如果Matcher對象為空白,則建立m=mp.matcher(mail);}else {m.reset(mail);//如果Matcher對象不為空白,則應用Matcher對象}String result=mail+(m.matches()?"是":"不是")+"一個有效郵箱地址!";System.out.println(result);}

  輸出結果:

[email protected]是一個有效郵箱地址![email protected]是一個有效郵箱地址![email protected]是一個有效郵箱地址!abc.com不是一個有效郵箱地址!

  

JavaSE-31 JavaRegex

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.