Java語言中的Regex

來源:互聯網
上載者:User

標籤:

Regex是什嗎?

Regex是一種強大而靈活的文本處理工具。初學Regex時,其文法是一個痛點,但它確實是一種簡潔、動態語言。Regex提供了一種完全通用的方式,能夠解決各種字串處理相關的問題:匹配、選擇、編輯以及驗證。一般來說,Regex就是以某種方式來描述字串。

日常例子

在文本中尋找“halu126”,我們通常會在尋找框中輸入“halu126”,這就是一個最簡單的Regex的例子,使用精確的匹配這樣的字串,如果我 們即想在文本中找到“halu126”,又想找到“Halu126”,卻不想找到“aaaHalu126bbbb”中的“Halu126”,該怎麼辦?

在linux中我們想查想列出所有的Java源檔案,通常會在終端中輸入:ls -all *.java,其中“*”是叫做萬用字元,而Regex比萬用字元更牛,它能更精確的描述你的需求。

Regex的構造摘要
構造
匹配
  字元
X
字元X
\\\\ 反斜線字元
\t
定位字元
\n
分行符號
\r
斷行符號符
  字元類
[abc]
a、b 或 c(簡單類)
[^abc]
任何字元,除了 a、b 或 c(否定)
[a-zA-Z]
a 到 z 或 A 到 Z,兩頭的字母包括在內(範圍)
[a-d[m-p]]
a 到 d 或 m 到 p:[a-dm-p](並集)
[a-z&&[def]]
d、e 或 f(交集)
[a-z&&[^bc]]
a 到 z,除了 b 和 c:[ad-z](減去)
  預定義字元類
.
任何字元
\d
數字:[0-9]
\D
非數字:[^0-9]
\s
空白字元:[\t\n\x0B\f\r]
\S
非空白字元:[^\s]
\w
單詞字元:[a-zA-Z_0-9]
\W
非單詞字元:[^\w]
  邊界匹配器
^
行的開頭
$
行的結尾
\b
單詞邊界
\B
非(單詞邊界)
  量詞
X?
X,一次或一次也沒有
X*
X,零次或多次
X+
X,一次或多次
X{n} X,恰好n次
X{n,} X,至少n次
X{n,m} X,至少n次,但是不超過m次
  Logical運算子
XY
X後跟Y
X|Y
X或者Y
(X)
X,作為擷取的群組
組和捕獲

擷取的群組可以通過從左至右計算其開括弧來編號。例如,在運算式中((A)(B(C)))中,存在四個這樣的組

1 ((A)(B(C)))
2
(A)
3
(B(C))
4
(C)
Java語言中Regex的不同處

在其他語言中,“ \\”表示“我想在Regex中插入一個普通的(字面上的)反斜線,請不要給它任何特殊的意義。”在Java語言中,“\\”表示“我要插入一個Regex的反斜線,所以其後的字元具有特殊的意思。”例如:“\\d”表示Java語言中Regex的一位元字。“\\\\”表示一個普通的反斜線。不過換行和定位字元之類的東西只需要使用單反斜線:“\n\t”。

量詞的類型:

量詞:描述了一個模式吸收(匹配)輸入文本的方式,也叫做重複限定符。
貪婪型:量詞總是貪婪的,除非有其他的選項被設定。貪婪運算式會為所有可能的模式發現儘可能多的匹配。
勉強型:用問號指定,這個量詞匹配滿足模式所需的最少字元數。因此也稱作懶惰的、最少匹配的、非貪婪的、或不貪婪的。
佔有型Java中專屬的。其他語言沒有。當Regex被應用於字元序列時,它會產生相當多的狀態,以便在匹配失敗時可以回溯。而“佔有的”量詞並不儲存這些中間狀態,因此他們可以防止回溯。他們常常用於防止Regex失控,因此可以使Regex執行起來更有效。

Greedy數量詞
Reluctant數量詞
Possessive數量詞
X?
X??
X?+
X*
X*?
X*+
X+
X+?
X++
X{n}
X{n}?
X{n}+
X{n,}
X{n,}?
X{n,}+
X{n,m}
X{n,m}?
X{n,m}+

量詞作用的運算式通常必須要使用圓括弧括起來。

String類中使用Regex的方法

matches(String regex)
split(String regex)
split(String regex, int limit)
replaceFirst(String regex, String replacement)
repalceAll(String regex, String replacement)

Java語言中表示Regex的類

在Java語言中與Regex相關的類都放在java.util.regex包。

  • *Pattern類:*pattern對象是一個Regex的編譯表示。Pattern類沒有公用構造方法。要建立一個Pattern對象,你必須首先調用其公用靜態編譯方法,它返回一個Pattern對象。該方法接受一個Regex作為它的第一個參數。
  • *Matcher類:*Matcher對象是對輸入字串進行解釋和匹配操作的引擎。與Pattern類一樣,Matcher也沒有公用構造方法。你需要調用Pattern對象的matcher方法來獲得一個Matcher對象。
  • *PatternSyntaxException:*PatternSyntaxException是一個非強制異常類,它表示一個Regex模式中的語法錯誤。

指定為字串的Regex必須首先被編譯為此類的執行個體。然後,可將得到的模式用於建立Matcher對象,依照Regex,該對象可以與任一字元序列匹配。執行匹配所涉及的所有狀態都駐留在匹配器中,所以多個匹配器可以共用同一模式。

因此,典型的調用順序是

1 Pattern pattern = Pattern.compile("a*b");2 Matcher matcher= pattern("aaaaaaab");3 matcher.XXX();

一個簡單的代碼如下:

 1 public class TestRegularExpression { 2     public static void main(String[] args) { 3         if(args.length < 2) { 4             print("Usage:\njava TestRegularExpression " + 5                     "characterSequence regularExpression+"); 6             System.exit(0); 7         } 8         print("Input: \"" + args[0] + "\""); 9         for(String arg : args) {10             print("Regular expression: \"" + arg + "\"");11             Pattern p = Pattern.compile(arg);12             Matcher m = p.matcher(args[0]);13             while(m.find()) {14                 print("Match \"" + m.group() + "\" at positions " +15                         m.start() + "-" + (m.end() - 1));16             }17         }18     }19 }
Pattern和Matcher類中常用的方法
 1 //使用Pattern類的靜態方法compile來編譯Regex,它會根據Regexregex產生一個Pattern對象。 2 Pattern pattern = Pattern.compile(String regex) 3 //檢查regex是否匹配整個CharSequence類型的input參數 4 Pattern.matches(String regex, CharSequence input) 5 //從匹配了regex的地方分割輸入字元序列input 6 pattern.split(CharSequence input) 7 //同String.split() 8 pattern.split(CharSequence input, int limit) 9 //根據模板pattern產生input的匹配器matcher10 Matcher matcher = pattern.matcher(CharSequence input);11 //從字元序列的開始位置(0位字元)迭代的向前遍曆字元序列,找到匹配模式的部分12 matcher.find()13 //從字元序列的第start位字元開始(以第start位字元作為搜尋的起點)迭代的向前遍曆字元序列,找到匹配模式的部分14 matcher.find(int start)15 //判斷整個輸入字元序列是否匹配Regex模式16 matcher.matches()17 //判斷該字元序列(不必是整個字元序列)的開始部分是否能夠匹配模式18 matcher.lookingAt()19 //該匹配器的模式中的分組數目20 matcher.groupCount()21 //返回前一次匹配操作(例如find())的第0組(即整個匹配)22 matcher.group()23 //返回在前一次操作期間指定的組號,如果沒有指定的組,返回null24 matcher.group(int group)25 //26 matcher.start()27 //返回前一次匹配操作中尋找到的組的起始索引28 matcher.start(int group)29 matcher.end()30 //返回前一次匹配操作中尋找到的組的最後一個字元索引加一的值31 matcher.end(int group)32 //將matcher對象重新設定到當前字元序列的起始位置33 matcher.reset()34 將現有的matcher對象應用到一個新的字元序列35 matcher.reset(CharSequence input)
使用Regex時要注意的事兒

要匹配一種情況,我們可以寫出多個可行的Regex,當然了,我們的目的並不是編寫最難理解的Regex,而是盡量編寫能夠完成任務的、最簡單以及最必要的Regex。

參考
    • Java編程思想
    • JDK API文檔
    • Regex30分鐘入門教程
    • RUNOOB中關於Regex的介紹

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.