javaRegex詳細總結,javaRegex

來源:互聯網
上載者:User

javaRegex詳細總結,javaRegex

Java 提供了功能強大的RegexAPI,在java.util.regex 包下。本教程介紹如何使用RegexAPI。

Regex

一個Regex是一個用於文本搜尋的文字模式。換句話說,在文本中搜尋出現的模式。例如,你可以用Regex搜尋網頁中的郵箱地址或超連結。

Regex樣本

下面是一個簡單的JavaRegex的例子,用於在文本中搜尋 http://

String text    =        "This is the text to be searched " +        "for occurrences of the http:// pattern.";String pattern = ".*http://.*";boolean matches = Pattern.matches(pattern, text);System.out.println("matches = " + matches);

範例程式碼實際上沒有檢測找到的 http:// 是否是一個合法超連結的一部分,如包含網域名稱和尾碼(.com,.net 等等)。代碼只是簡單的尋找字串 http:// 是否出現。

Java6 中關於Regex的API

本教程介紹了Java6 中關於Regex的API。

Pattern (java.util.regex.Pattern)

類 java.util.regex.Pattern 簡稱 Pattern, 是JavaRegexAPI中的主要入口,無論何時,需要使用Regex,從Pattern 類開始

Pattern.matches()

檢查一個Regex的模式是否匹配一段文本的最直接方法是調用靜態方法Pattern.matches(),樣本如下:

String text    =        "This is the text to be searched " +        "for occurrences of the pattern.";String pattern = ".*is.*";boolean matches = Pattern.matches(pattern, text);System.out.println("matches = " + matches);

上面代碼在變數 text 中尋找單詞 “is” 是否出現,允許”is” 前後包含 0或多個字元(由 .* 指定)
Pattern.matches() 方法適用於檢查 一個模式在一個文本中出現一次的情況,或適用於Pattern類的預設設定。

如果需要匹配多次出現,甚至輸出不同的匹配文本,或者只是需要非預設設定。需要通過Pattern.compile() 方法得到一個Pattern 執行個體。

Pattern.compile()

如果需要匹配一個Regex在文本中多次出現,需要通過Pattern.compile() 方法建立一個Pattern對象。樣本如下

String text    =        "This is the text to be searched " +        "for occurrences of the http:// pattern.";String patternString = ".*http://.*";Pattern pattern = Pattern.compile(patternString);

可以在Compile 方法中,指定一個特殊標誌:
Pattern pattern = Pattern.compile(patternString, Pattern.CASE_INSENSITIVE);
Pattern 類包含多個標誌(int 類型),這些標誌可以控制Pattern 匹配模式的方式。上面代碼中的標誌使模式比對是忽略大小寫

Pattern.matcher()

一旦獲得了Pattern對象,接著可以獲得Matcher對象。Matcher 樣本用於匹配文本中的模式.樣本如下
Matcher matcher = pattern.matcher(text);

Matcher類有一個matches()方法,可以檢查文本是否匹配模式。以下是關於Matcher的一個完整例子

String text    =        "This is the text to be searched " +        "for occurrences of the http:// pattern.";String patternString = ".*http://.*";Pattern pattern = Pattern.compile(patternString, Pattern.CASE_INSENSITIVE);Matcher matcher = pattern.matcher(text);boolean matches = matcher.matches();System.out.println("matches = " + matches);
Pattern.split()

Pattern 類的 split()方法,可以用Regex作為分隔字元,把文本分割為String類型的數組。樣本:

String text = "A sep Text sep With sep Many sep Separators";String patternString = "sep";Pattern pattern = Pattern.compile(patternString);String[] split = pattern.split(text);System.out.println("split.length = " + split.length);for(String element : split){    System.out.println("element = " + element);}

上例中把text 文本分割為一個包含5個字串的數組。

Pattern.pattern()

Pattern 類的 pattern 返回用於建立Pattern 對象的Regex,樣本:

String patternString = "sep";Pattern pattern = Pattern.compile(patternString);String pattern2 = pattern.pattern();

上面代碼中 pattern2 值為sep ,與patternString 變數相同。

Matcher (java.util.regex.Matcher)

java.util.regex.Matcher 類用於匹配一段文本中多次出現一個Regex,Matcher 也適用於多文本中匹配同一個Regex。

Matcher 有很多有用的方法,詳細請參考官方JavaDoc。這裡只介紹核心方法。

以下代碼示範如何使用Matcher

String text    =        "This is the text to be searched " +        "for occurrences of the http:// pattern.";String patternString = ".*http://.*";Pattern pattern = Pattern.compile(patternString);Matcher matcher = pattern.matcher(text);boolean matches = matcher.matches();

首先建立一個Pattern,然後得到Matcher ,調用matches() 方法,返回true 表示模式比對,返回false表示不匹配。
可以用Matcher 做更多的事。

建立Matcher

通過Pattern 的matcher() 方法建立一個Matcher。

String text    =        "This is the text to be searched " +        "for occurrences of the http:// pattern.";String patternString = ".*http://.*";Pattern pattern = Pattern.compile(patternString);Matcher matcher = pattern.matcher(text);
matches()

Matcher 類的 matches() 方法用於在文本中匹配Regex

boolean matches = matcher.matches();

如果文本匹配Regex,matches() 方法返回true。否則返回false。

matches() 方法不能用於尋找Regex多次出現。如果需要,請使用find(), start() 和 end() 方法。

lookingAt()

lookingAt() 與matches() 方法類似,最大的不同是,lookingAt()方法對文本的開頭匹配Regex;而
matches() 對整個文本匹配Regex。換句話說,如果Regex匹配文本開頭而不匹配整個文本,lookingAt() 返回true,而matches() 返回false。 樣本:

String text    =        "This is the text to be searched " +        "for occurrences of the http:// pattern.";String patternString = "This is the";Pattern pattern = Pattern.compile(patternString, Pattern.CASE_INSENSITIVE);Matcher matcher = pattern.matcher(text);System.out.println("lookingAt = " + matcher.lookingAt());System.out.println("matches   = " + matcher.matches());

上面的例子分別對文本開頭和整個文本匹配Regex “this is the”. 匹配文本開頭的方法(lookingAt()) 返回true。

對整個文本匹配Regex的方法 (matches()) 返回false,因為 整個文本包含多餘的字元,而 Regex要求文本精確匹配”this is the”,前後又不能有額外字元。

find() + start() + end()

find() 方法用於在文本中尋找出現的Regex,文本是建立Matcher時,通過 Pattern.matcher(text) 方法傳入的。如果在文本中多次匹配,find() 方法返回第一個,之後每次調用 find() 都會返回下一個。

start() 和 end() 返回每次匹配的字串在整個文本中的開始和結束位置。實際上, end() 返回的是字串末尾的後一位,這樣,可以在把 start() 和 end() 的傳回值直接用在String.substring() 裡。

String text    =        "This is the text which is to be searched " +        "for occurrences of the word 'is'.";String patternString = "is";Pattern pattern = Pattern.compile(patternString);Matcher matcher = pattern.matcher(text);int count = 0;while(matcher.find()) {    count++;    System.out.println("found: " + count + " : "  + matcher.start() + " - " + matcher.end());}

這個例子在文本中找到模式 “is” 4次,輸出如下:

 found: 1 : 2 - 4 found: 2 : 5 - 7 found: 3 : 23 - 25 found: 4 : 70 - 72
reset()

reset() 方法會重設Matcher 內部的 匹配狀態。當find() 方法開始匹配時,Matcher 內部會記錄截至當前尋找的距離。調用 reset() 會重新從文本開頭尋找。

也可以調用 reset(CharSequence) 方法. 這個方法重設Matcher,同時把一個新的字串作為參數傳入,用於代替建立 Matcher 的原始字串。

group()

假設想在一個文本中尋找URL連結,並且想把找到的連結提取出來。當然可以通過 start()和 end()方法完成。但是用group()方法更容易些。

分組在Regex中用括弧表示,例如:
(John)
此Regex匹配John, 括弧不屬於要匹配的文本。括弧定義了一個分組。當Regex匹配到文本後,可以訪問分組內的部分。

使用group(int groupNo) 方法訪問一個分組。一個Regex可以有多個分組。每個分組由一對括弧標記。想要訪問Regex中某分組匹配的文本,可以把分組編號傳入 group(int groupNo)方法。

group(0) 表示整個Regex,要獲得一個有括弧標記的分組,分組編號應該從1開始計算。

String text    =  "John writes about this, and John writes about that," +                        " and John writes about everything. "  ;String patternString1 = "(John)";Pattern pattern = Pattern.compile(patternString1);Matcher matcher = pattern.matcher(text);while(matcher.find()) {    System.out.println("found: " + matcher.group(1));}
以上代碼在文本中搜尋單詞John.從每個匹配文本中,提取分組1,就是由括弧標記的部分。輸出如下
 found: John found: John found: John
多分組

上面提到,一個Regex可以有多個分組,例如:
(John) (.+?)
這個運算式匹配文本”John” 後跟一個空格,然後跟1個或多個字元,最後跟一個空格。你可能看不到最後的空格。

這個運算式包括一些字元有特別意義。字元 點 . 表示任一字元。 字元 + 表示出現一個或多個,和. 在一起表示 任何字元,出現一次或多次。字元? 表示 匹配儘可能短的文本。

完整代碼如下

String text    =          "John writes about this, and John Doe writes about that," +                  " and John Wayne writes about everything."        ;String patternString1 = "(John) (.+?) ";Pattern pattern = Pattern.compile(patternString1);Matcher matcher = pattern.matcher(text);while(matcher.find()) {    System.out.println("found: " + matcher.group(1) +                       " "       + matcher.group(2));}
注意代碼中引用分組的方式。代碼輸出如下
 found: John writes found: John Doe found: John Wayne
嵌套分組

在Regex中分組可以嵌套分組,例如
((John) (.+?))
這是之前的例子,現在放在一個大分組裡.(運算式末尾有一個空格)。

當遇到嵌套分組時, 分組編號是由左括弧的順序確定的。上例中,分組1 是那個大分組。分組2 是包括John的分組,分組3 是包括 .+? 的分組。當需要通過groups(int groupNo) 引用分組時,瞭解這些非常重要。

以下代碼示範如何使用嵌套分組

String text    =          "John writes about this, and John Doe writes about that," +                  " and John Wayne writes about everything."        ;String patternString1 = "((John) (.+?)) ";Pattern pattern = Pattern.compile(patternString1);Matcher matcher = pattern.matcher(text);while(matcher.find()) {    System.out.println("found:   ");}
輸出如下
 found: found: found: 
replaceAll() + replaceFirst()

replaceAll() 和 replaceFirst() 方法可以用於替換Matcher搜尋字串中的一部分。replaceAll() 方法替換全部匹配的Regex,replaceFirst() 只替換第一個匹配的。

在處理之前,Matcher 會先重設。所以這裡的匹配運算式從文本開頭開始計算。

樣本如下

String text    =          "John writes about this, and John Doe writes about that," +                  " and John Wayne writes about everything."        ;String patternString1 = "((John) (.+?)) ";Pattern pattern = Pattern.compile(patternString1);Matcher matcher = pattern.matcher(text);String replaceAll = matcher.replaceAll("Joe Blocks ");System.out.println("replaceAll   = " + replaceAll);String replaceFirst = matcher.replaceFirst("Joe Blocks ");System.out.println("replaceFirst = " + replaceFirst);

輸出如下

replaceAll = Joe Blocks about this, and Joe Blocks writes about that,and Joe Blocks writes about everything.replaceFirst = Joe Blocks about this, and John Doe writes about that,and John Wayne writes about everything.

輸出中的換行和縮排是為了可讀而增加的。

注意第1個字串中所有出現 John 後跟一個單詞 的地方,都被替換為 Joe Blocks 。第2個字串中,只有第一個出現的被替換。

appendReplacement() + appendTail()

appendReplacement() 和 appendTail() 方法用於替換輸入文本中的字串短語,同時把替換後的字串附加到一個 StringBuffer 中。

當find() 方法找到一個匹配項時,可以調用 appendReplacement() 方法,這會導致輸入字串被增加到StringBuffer 中,而且匹配文本被替換。 從上一個匹配文本結尾處開始,直到本次匹配文本會被拷貝。

appendReplacement() 會記錄拷貝StringBuffer 中的內容,可以持續調用find(),直到沒有匹配項。

直到最後一個匹配項目,輸入文本中剩餘一部分沒有拷貝到 StringBuffer. 這部分文本是從最後一個匹配項結尾,到文本末尾部分。通過調用 appendTail() 方法,可以把這部分內容拷貝到 StringBuffer 中.

String text    =          "John writes about this, and John Doe writes about that," +                  " and John Wayne writes about everything."        ;String patternString1 = "((John) (.+?)) ";Pattern      pattern      = Pattern.compile(patternString1);Matcher      matcher      = pattern.matcher(text);StringBuffer stringBuffer = new StringBuffer();while(matcher.find()){    matcher.appendReplacement(stringBuffer, "Joe Blocks ");    System.out.println(stringBuffer.toString());}matcher.appendTail(stringBuffer);System.out.println(stringBuffer.toString());
 注意我們在while迴圈中調用appendReplacement() 方法。在迴圈完畢後調用appendTail()。 代碼輸出如下:
 Joe Blocks Joe Blocks about this, and Joe Blocks Joe Blocks about this, and Joe Blocks writes about that, and Joe Blocks Joe Blocks about this, and Joe Blocks writes about that, and Joe Blocks writes about everything.
Java Regex文法

為了更有效使用Regex,需要瞭解Regex文法。Regex文法很複雜,可以寫出非常進階的運算式。只有通過大量的練習才能掌握這些文法規則。

本篇文字,我們將通過例子瞭解Regex文法的基礎部分。介紹重點將會放在為了使用Regex所需要瞭解的核心概念,不會涉及過多的細節。詳細解釋,參見 Java DOC 中的 Pattern 類.

基本文法

在介紹進階功能前,我們先快速探索下Regex的基本文法。

字元

是Regex中最經常使用的的一個運算式,作用是簡單的匹配一個確定的字元。例如:
John
這個簡單的運算式將會在一個輸入文本中匹配John文本。
可以在運算式中使用任意英文字元。也可以使用字元對於的8進位,16進位或unicode編碼錶示。例如:
101
\x41
\u0041

以上3個運算式 都表示大寫字元A。第一個是8進位編碼(101),第2個是16進位編碼(41),第3個是unicode編碼(0041).

字元分類

字元分類是一種結構,可以針對多個字元匹配而不只是一個字元。換句話說,一個字元分類匹配輸入文本中的一個字元,對應字元分類中多個允許字元。例如,你想匹配字元 a,b 或c,運算式如下:
[abc]

用一對方括弧[] 表示字元分類。方括弧本身並不是要匹配的一部分。

可以用字元分類完成很多事。例如想要匹配單詞John,首字母可以為大寫和小寫J.
[Jj]ohn

字元分類[Jj] 匹配J或j,剩餘的 ohn 會準確匹配字元ohn.

預定義字元分類

Regex中有一些預定義的字元分類可以使用。例如, \d 表示任一數字, \s 表示任意空白字元,\w 表示任意單詞字元。
預定義字元分類不需要括在方括弧裡,當然也可以組合使用
\d
[\d\s]

第1個匹配任一數字,第2個匹配任一數字或空白符。
完整的預定義字元分類列表,在本文最後列出。

邊界匹配

Regex支援匹配邊界,例如單詞邊界,文本的開頭或末尾。例如,\w 匹配一個單詞,^匹配行首,$ 匹配行尾。
^This is a single line$
上面的運算式匹配一行文本,只有文本 This is a single line。注意其中的行首和行尾標誌,表示不能有任何文本在文本的前面後後面,只能是行首和行尾。
完整的匹配邊界列表,在本文最後列出。

量詞匹配

量詞可以匹配一個運算式多次出現。例如下列運算式匹配字母A 出現0次或多次。
A*

量詞 * 表示0次或多次。+ 表示1次或多次。? 表示0次或1次。還有些其他量詞,參見本文後面的列表。

量詞匹配分為 饑餓模式,貪婪模式,獨佔模式。饑餓模式 匹配儘可能少的文本。貪婪模式比對儘可能多的文本。獨佔模式比對儘可能多的文本,甚至導致剩餘運算式匹配失敗。

以下示範饑餓模式,貪婪模式,獨佔模式區別。假設以下文本:
John went for a walk, and John fell down, and John hurt his knee.

饑餓模式下 運算式:
John.*?
這個運算式匹配John 後跟0個或多個字元。 . 表示任一字元。* 表示0或多次。? 跟在 * 後面,表示 * 採用饑餓模式。
饑餓模式下,量詞只會匹配儘可能少的字元,即0個字元。上例中的運算式將會匹配單詞John,在輸入文本中出現3次。

如果改為貪婪模式,運算式如下:
John.*
貪婪模式下,量詞會匹配儘可能多的字元。現在運算式會匹配第一個出現的John,以及在貪婪模式下 匹配剩餘的所有字元。這樣,只有一個匹配項。

最後,我們改為獨佔模式:
John.*+hurt
*後跟+ 表示獨佔模式量詞。

這個運算式在輸入文本中沒有匹配項,儘管文本中包括 John 和 hurt. 為什麼會這樣? 因為 .*+ 是獨佔模式。與貪婪模式下,儘可能多的匹配文本,以使整個運算式匹配不同。獨佔模式會儘可能的多的匹配,但不考慮運算式剩餘部分是否能匹配上。

.*+ 將會匹配第一個John之後的所有字元,這會導致運算式中剩餘的 hurt 沒有匹配項。如果改為貪婪模式,會有一個匹配項。運算式如下:
John.*hurt

邏輯操作符

Regex支援少量的邏輯運算(與,或,非)。
與操作是預設的,運算式 John ,意味著J 與 o與h與n。
或操作需要顯示指定,用 | 表示。例如運算式 John|hurt 意味著John 或 hurt 。

字元字元分類

內建字元分類邊界匹配

 

量詞

 

我有一個公眾號,經常會分享一些Java技術相關的乾貨;如果你喜歡我的分享,可以用搜尋“Java團長”或者“javatuanzhang”關注。

 

參考:

  • Java Regex | 菜鳥教程
  • JavaRegex的文法與樣本
  • JAVA Regex (超詳細)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.