首先說一下java正則表達式的重點概念:
第一、相關類:Pattern、Matcher
第二、典型的調用順序是
Pattern p = Pattern.compile("a*b");
Matcher m = p.matcher("aaaaab");
boolean b = m.matches();
在僅使用一次正則表達式時,可以方便地通過此類定義 matches 方法。此方法編譯表達式並在單個調用中將輸入序列與其匹配。
語句 boolean b = Pattern.matches("a*b", "aaaaab");等效於上面的三個語句,儘管對於重複的匹配而言它效率不高,因爲它不允許重用已編譯的模式。
此類的實例是不可變的,可供多個併發線程安全使用。Matcher 類的實例用於此目的則不安全。
第三、正則表達式的構造摘要
字符類
[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](減去)
[a-z&&[^m-p]] a 到 z,而非 m 到 p:[a-lq-z](減去)
說明:
[]表示範圍--某一個字符的範圍
^表示非
&&表示
預定義字符類
. 任何字符(與行結束符可能匹配也可能不匹配)
\d 數字:[0-9]
\D 非數字: [^0-9]
\s 空白字符:[ \t\n\x0B\f\r]
\S 非空白字符:[^\s]
\w 單詞字符:[a-zA-Z_0-9]
\W 非單詞字符:[^\w]
說明:預定義字符類和字符類部分可以互換。如:[0-9] == \d
數量詞
X? :X出現一次或一次也沒有
X* :X出現零次或多次
X+ :X出現一次或多次
X{n} :X出現恰好 n 次
X{n,} :X出現至少 n 次
X{n,m} :X出現至少 n 次,但是不超過 m 次
例子:a?bc 表示在一個字符串中a出現0次或1次,abc或bc都可以匹配,aabc不可匹配
捕獲組和非捕獲組
組的表示方法:
捕獲組
捕獲組可以通過從左到右計算其開括號來編號。例如,在表達式 ((A)(B(C))) 中,存在四個這樣的組:
1 ((A)(B(C)))
2 \A
3 (B(C))
4 (C)
組零始終代表整個表達式
之所以這樣命名捕獲組是因爲在匹配中,保存了與這些組匹配的輸入序列的每個子序列。捕獲的子序列稍後可以通過 Back 引用在表達式中使用,也可以在匹配操作完成後從匹配器檢索。
Back 引用 是說在後面的表達式中我們可以使用組的編號來引用前面的表達式所捕獲到的文本序列(是文本不是正則)。
例如 ([" ']).* \1 其中使用了分組,\1就是對引號這個分組的引用,它匹配包含在兩個引號或者兩個單引號中的所有字符串,如,"abc" 或 " ' " 或 ' " ' ,但是請注意,它並不會對" a'或者 'a"匹配。原因上面已經說明,Back引用只是引用文本而不是表達式。
非捕獲組
以 (?) 開頭的組是純的非捕獲 組,它不捕獲文本,也不針對組合計進行計數。就是說,如果小括號中以?號開頭,那麼這個分組就不會捕獲文本,當然也不會有組的編號,因此也不存在Back 引用。
在Java中,支持的非捕獲組,有如下幾種:
(?=X) X,通過零寬度的正 lookahead 即左側匹配
(?!X) X,通過零寬度的負 lookahead 即左側匹配
(?<=X) X,通過零寬度的正 lookbehind 即右側匹配
(?<!X) X,通過零寬度的負 lookbehind 即右側匹配
這四個非捕獲組用於匹配表達式X,但是不包含表達式的文本。
(?=X )
零寬度正先行斷言。僅當子表達式 X 在 此位置的右側匹配時才繼續匹配。例如,\w+(?=\d) 與後跟數字的單詞匹配,而不與該數字匹配。此構造不會回溯。
(?!X)
零寬度負先行斷言。僅當子表達式 X 不在 此位置的右側匹配時才繼續匹配。例如,例如,\w+(?!\d) 與後不跟數字的單詞匹配,而不與該數字匹配。
(?<=X)
零寬度正後發斷言。僅當子表達式 X 在 此位置的左側匹配時才繼續匹配。例如,(?<=19)99 與跟在 19 後面的 99 的實例匹配。此構造不會回溯。
(?<!X)
零寬度負後發斷言。僅當子表達式 X 不在此位置的左側匹配時才繼續匹配。例如,(?<!19)99 與不跟在 19 後面的 99 的實例匹配
說明:
非捕獲組中四個表達式的區別:
(?=X ) 和(?!X)用於右側匹配
(?<=X)和(?<!X)用於左側匹配
舉例:
上面都是理論性的介紹,這裏就使用一些例子來說明一下問題:
1、測試匹配性 (abc)+def(?<!4)56(?=9) 這裏的含義就是匹配 以一個或多個abc開頭後跟def的文本,而且後面的文本56前面不能是4,後面必須是9組成。因此,可以匹配如下文本 abcdef5569 ,與abcdef4569不匹配。
2 、提取字符串 提取 da12bka3434bdca4343bdca234bm
提取包含在字符a和b之間的數字,但是這個a之前的字符不能是c,b後面的字符必須是d才能提取。
例如這裏就只有3434這個數字滿足要求。那麼我們怎麼提取呢?
首先我們寫出提取這個字符串的表達式: (?<!c)a(\d+)bd 這裏就只有一個捕獲組(\d+)
JAVA代碼片段如下:
Java代碼
Pattern p = Pattern.compile("(?<!c)a(\\d+)bd");
Matcher m = p.matcher("da12bca3434bdca4343bdca234bm");
while(m.find()){
System.out.println(m.group(1)); //我們只要捕獲組1的數字即可。結果 3434
System.out.println(m.group(0)); // 0組是整個表達式,看這裏,並沒有提煉出(?<!c)的字符 。結果 a3434bd
}
可以看到,非捕獲組,最後是不會返回結果的,因爲它本身並不捕獲文本。
Java代碼
package cn.com.kn.test;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class PatternTest {
public void testParttern(){
//表達式的功能:驗證必須爲數字(整數或小數)
String pattern = "[0-9]+(.[0-9]+)?";
//對()的用法總結:將()中的表達式作爲一個整體進行處理,必須滿足他的整體結構纔可以。
//(.[0-9]+)? :表示()中的整體出現一次或一次也不出現
Pattern p = Pattern.compile(pattern);
Matcher m = p.matcher("2");
boolean b = m.matches();
if(b){
System.out.println("istrue:"+b);
}
}
public static void main(String[] args) {
PatternTest pt = new PatternTest();
// pt.testFormat("2");
pt.testParttern();
}
}
正則表達式
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class CDataChange
{
public static void main(String[] args)
{
String string1;
string1 = "aaeDddse";
boolean bRet = Pattern.compile("[^A-Za-z]").matcher(string1).find();
if(bRet)
{
System.out.print("yes");
}
else
{
System.out.print("no");
}
}
}