java中的正規表達式遵循了像python,unix中的一些工具相同的文法,使得正規表達式可以通用。
正規表達式是強大而靈活的文本處理工具。他們可以讓我們以變成程式設計的方式找到文本中符合某種模式的内容,
然後我們能夠對這些内容進行處理,例如:比對、驗證、選擇等等。
在jdk文檔的pattern類中有更加詳細的模式說明
構造 比對
字元
x 字元x
/uhhhh 用16進制0xhhhh表示的unicode字元
/t 制表符
/n 換行符
/r 回車
/f 換頁
字元類
[abc] a|b|c
[^abc] 除了a,b,c之外的字元
[a-z] 範圍
[ab[cd]] 并集
[a-z&&[abc]] 交集
預定義
. 任意字元
/s 空白字元(/t,/n,/r,/f)
/s 非空白字元
/d 數字[0-9]
/w 單詞字元[a-za-z_0-9]
邏輯運算
xy x後面跟y
x|y x或y
(x) 捕獲組,能夠用表達式/i引用第i個組
邊界比對
^ 一行的開始
$ 一行的結束
/b 詞界
/b 非詞界
/g 上一級的結尾
量詞
x? 0或1
x* 0或多
x+ 1或多
x{n} 恰好n次
x{n,} 恰好n次
x{n,m} >=n但是<m
上面就算是一些基本的文法了,下面我們來看一下在java中應該如何進行使用
pattern p = pattern.compile("a*b");
matcher m = p.matcher("aaaaab");
system.out.println(m.matches());
其中pattern為正規表達式的編譯表現形式,它需要接收實作了charsequence接口的類,比如string,stringbuffer等,然後編譯成正規表達式。
然後使用了p.matcher(string s)方法得到比對器matcher.通過比對器提供的方法我們能夠能夠找到s中與模式相比對的這個子字元串以及其所在的位置等等。
p.matcher方法表示的是将整個字元串與模式進行比對,能夠比對則傳回true。比對
下面就來看看具體我們能夠進行哪些操作。
這之前還有一點要說的是,java語言中的表達式與其他語言在處理反斜杠的方式有些不同。
其他語言中"//"意味着我想在一個正規表達式中插入一個無格式的字面意義上的反斜杠。
而在java中,"//"意味着我正在插入一個正規表達式反斜杠,那麼其後面的字元具有特殊的意義。例如我們想表達一個或者多個字元我們的正規表達式需要是"//w+"的這種形式。,如果我們想插入一個字面意義的反斜杠則是"////"。但是像制表符這樣的字元隻需要用到一個反斜杠:"/n/t"。
find()嘗試查找與該模式比對的輸入序列的下一個子序列。從序列的開頭開始,如果成功調用了一次這個方法,下一次調用之後會從比對
find(int start)重置此比對器,然後從輸入序列中嘗試查找比對該模式的,從指定索引開始的下一個子序列。
group() 相當于group(0)
group(i) 傳回上一次比對捕獲的子序列。0表示的就是整個子序列。
a(b(c))d 這個表達式表示了三個組0 abcd,1 bc, 2 c
可以使用groupcount()目前比對子序列中的分組的數目。第0組不包括在内。
start(int group)傳回在前一次比對中找到的該組的起始下标。end(int group)傳回在前一次比對操作中族的最後一個字元的下标加1
看例子:
正規表達式為:(?m)(//s+)//s+((//s+)//s+(//s+))$
我們先來看一下它表達的意思。?m叫做模式标記,暫時記住它的意思是按照每一行來算末尾。
然後去掉分組的括号來看它表達的意思是:若幹非空白符,若幹空白符,若幹非空白符,若幹空白符,若幹非空白符,結尾。顯然這是要擷取每一行的最後三個單詞。
按照第一行為例,會比對到the slithy toves。那麼0組就是the slithy toves。1組就是the。。。
m.start(i)得到組的開始的下标 m.start()方法相當于調用了m.start(0);
上面示範了兩種設定模式标記的方式。
常用的有pattern.case_insensitive (?i)大小寫不敏感
pattern.comments (?x)空格将被忽略掉。并且以#開頭的注釋也會被忽略
patten.multiline (?m)在多行模式下,表達式'^'和'$'分别比對一行的開始和結束。
使用正規表達式的操作:
實際上s.split()方法在源代碼中就是調用了pattern.compile("//.").split(s,0)的方法。
它表示以正規表達式為分界點,對實作了charsequence接口的對象進行分割。split(s, limit)中的limit表示分為幾項。分割之後剩下的所有内容為最後一項。
要注意使用特殊符号作為分割符的時候需要使用其正規表達式的字面意義。
主要有如下的可用的方法:
另外還有個方法需要說一下m.reset()方法将會把其置為開始的狀态。
replacefirst("regex", "replace")替換在輸入序列中查找到的第一個子序列。
replaceall(...,...)替換在輸入序列中查找到的所有子序列。
m.appendreplacement(stringbuffer , "replace");
這個語句在relace中有$符号和沒有$符号的表現是不相同的。
沒有的時候表示把輸入序列中查找到的比對的子序列使用replace字元替換到,并且把start()位置和end()位置之間的字元串壓入sb。
有$符号的意義在于,把輸入序列中比對的序列中的對應的組的後面加入replace符号,然後壓入sb。
m.appendtail(sb)表示把end()位置之後的所有的字元串都壓入sb。
在使用正規表達式的時候一定要注意他們時刻的指針指向情況,和注意他們是周遊執行的。