java.util.regex
是一個用正則表達式所訂製的模式來對字符串進行匹配工做的類庫包。它包括兩個類:Pattern
和Matcher
。Pattern是一個正則表達式經編譯後的表現模式。Matcher對象是一個狀態機器,它依據Pattern對象作爲匹配模式對字符串展開匹配檢查。 首先一個Pattern實例訂製了一個所用語法與PERL的相似的正則表達式經編譯後的模式,而後一個Matcher實例在這個給定的Pattern實例的模式控制下進行字符串的匹配工做。html
詳細摘要請看jdk中文文檔,下面我只是列出一些常用的java
構造 | 匹配 |
---|---|
. | 任何字符(與行結束符可能匹配也可能不匹配) |
\d | 數字:[0-9] |
\D | 非數字: [^0-9] |
\s | 空白字符:[ \t\n\x0B\f\r] |
\S | 非空白字符:[^\s] |
\w | 單詞字符:[a-zA-Z_0-9] |
\W | 非單詞字符:[^\w] |
[abc] | a、b 或 c(簡單類) |
[^abc] | 任何字符,除了 a、b 或 c(否認) |
[a-zA-Z] | a 到 z 或 A 到 Z,兩頭的字母包括在內(範圍) |
^ | 行的開頭 |
$ | 行的結尾 |
X? | X,一次或一次也沒有 |
X* | X,零次或屢次 |
X+ | X,一次或屢次 |
X{n} | X,剛好 n 次 |
X{n,} | X,至少 n 次 |
X{n,m} | X,至少 n 次,可是不超過 m 次 |
正則表達式的編譯表示形式,學過
python
的都知道這個和python的正則表達式有殊途同歸之妙。 可是它的構造方法是私有的,所以不能直接建立對象,可是能夠調用它的靜態方法返回一個對象,下面會詳細介紹python
Pattern
類用於建立一個正則表達式,也能夠說建立一個匹配模式,它的構造方法是私有的,不能夠直接建立,但能夠經過Pattern.complie(String regex)
簡單工廠方法建立一個正則表達式,代碼以下:
//採用的complie(String regex) Pattern pattern = Pattern.compile("\\d+"); //採用的是complie(String regex,int flag)其中flag表示標誌,下面的標誌表示忽略字母大小寫,詳細的字段請看文檔 Pattern pattern=Pattern.compile("(CHEN)(\\D*)(\\d*)",Pattern.CASE_INSENSITIVE);
Pattern compile(String regex)
用於建立Pattern對象Pattern compile(String regex,int flags)
用於建立Pattern對象,而且指定了標誌(好比忽略字母大小寫)int flags()
返回此模式的匹配標誌String pattern()
返回在其中編譯過此模式的正則表達式。
String[] split(CharSequence input)
根據此模式的正則表達式將輸入的字符串拆分紅String數組,默認的都是所有拆分開
//給出正則表達式用於匹配數字(0-9) Pattern pattern = Pattern.compile("\\d+"); String str = "我是陳加兵456鄭元梅34擦市場的邏輯啊"; String[] splits = pattern.split(str, 2); //結果:[我是陳加兵,鄭元梅34擦市場的邏輯啊]
String[] split(CharSequence input,int limit)
將字符串按照正則表達式表示的內容進行分組,若是limit>0那麼就分紅limit個組,若是limit<0就按照默認所有分開
//給出正則表達式用於匹配數字(0-9) Pattern pattern = Pattern.compile("\\d+"); String str = "我是陳加兵456鄭元梅34擦市場的邏輯啊"; String[] splits = pattern.split(str, 2); //結果:[我是陳加兵,鄭元梅34擦市場的邏輯啊]
Pattern.matches(String regex,CharSequence input)
是一個靜態方法,用於快速匹配字符串,該方法適合用於只匹配一次,且匹配所有字符串
Pattern.matches("\\d+","2223");//返回true Pattern.matches("\\d+","2223aa");//返回false,須要匹配到全部字符串才能返回true,這裏aa不能匹配到 Pattern.matches("\\d+","22bb23");//返回false,須要匹配到全部字符串才能返回true,這裏bb不能匹配到
Matcher matcher(CharSequence input)
建立匹配給定輸入與此模式的匹配器,如今只是先了解如下,下面會詳細解釋Matcher這個類
Pattern p=Pattern.compile("\\d+"); Matcher m=p.matcher("22bb23");
Pattern
類只能作一些簡單的匹配操做,要想獲得更強更便捷的正則匹配操做,那就須要將Pattern與Matcher一塊兒合做.Matcher類提供了對正則表達式的分組支持,以及對正則表達式的屢次匹配支持.
Matcher類和Pattern類同樣它的構造方法一樣是私有的,所以不能直接構造對象,可是上面咱們說過Pattern類中有一個方法能夠返回一個Matcher對象(matcher(CharSequence input)
)正則表達式
boolean mathces()
嘗試將整個區域與模式匹配(針對的是整個字符串,若是整個字符串未徹底匹配,那麼返回false,若是徹底匹配那麼返回true)
Pattern pattern=Pattern.compile("\\d+"); //建立Pattern對象 String str="I am hreo 1234"; //須要匹配的字符串 Matcher matcher=pattern.matcher(str); //並無徹底匹配,所以返回false,若是str="123445",那麼就會返回true System.out.println(matcher.matches());
boolean lookingAt()
嘗試從給定字符串的開頭開始匹配,若是有子字符串匹配成功,那麼返回true(針對的不是整個字符串,而是從開頭開始,若是開頭有一段字符串匹配成功,那麼返回true)
Pattern pattern=Pattern.compile("\\d+"); //建立Pattern對象 String str="1234 I am a hero"; //須要匹配的字符串 Matcher matcher=pattern.matcher(str); //開頭的1234匹配到了,所以返回true,若是str="I am a hero 1234"將返回false System.out.println(matcher.lookingAt());
int start()
匹配到的字符串的第一個元素的索引,若是沒有匹配到調用此方法將會報錯int end()
匹配到的字符串的最後一個元素的索引,若是沒有匹配到調用此方法將會報錯String group()
返回的是匹配到的字符串,若是沒有匹配到調用此方法將會報錯
Pattern pattern=Pattern.compile("\\d+"); //建立Pattern對象 String str="1234 I am a hero 33455"; //須要匹配的字符串 Matcher matcher=pattern.matcher(str); if(matcher.lookingAt()) { System.out.println("開始匹配到下標爲"+matcher.start()); //0 System.out.println("匹配結束的下標爲"+matcher.end()); //4 System.out.println("匹配的字符串爲"+matcher.group()); //1234 }
boolean find()
查找整個字符串,若是在任意位置有一段字符串可以匹配成功,那麼返回true(任意位置),而後若是再次調用這個查找的話,那麼就從上次查找到的末尾開始匹配,也就是說查找的是下一個子序列了
Pattern pattern=Pattern.compile("\\d+"); //建立Pattern對象 String str="1234 I am a hero 6666 chenjiabing8888"; //須要匹配的字符串 Matcher matcher=pattern.matcher(str); while(matcher.find()) //若是還有匹配的字符序列 { System.out.println("開始匹配到下標爲"+matcher.start()); System.out.println("匹配結束的下標爲"+matcher.end()); System.out.println("匹配的字符串爲"+matcher.group()); } /*結果以下: * 開始匹配到下標爲0 匹配結束的下標爲4 匹配的字符串爲1234 開始匹配到下標爲17 匹配結束的下標爲21 匹配的字符串爲6666 開始匹配到下標爲33 匹配結束的下標爲37 匹配的字符串爲8888 */ /* * 從上面返回的結果能夠知道,find()能夠匹配屢次只要這個字符串還有能夠匹配, * 而且每次的匹配字段的開始下標都是上一次匹配的結束字母的下一個下標 */
boolean find(int start)
從指定的索引start位置開始匹配,這個用於重置find()匹配器,由於直接使用find()它的每次開始的索引都是不同的
String group(int num)
返回指定分組匹配到的字符串,group(0)表示匹配到的整個字符串,group(1) 表示匹配到的第一個字符(便是第一個括號中匹配的模式)int groupCount()
返回匹配到的分組個數String replaceAll(String str)
將全部於模式相匹配的 字符串所有替換程指定的字符串str,返回的是替換後的文本String replaceFirst(String str)
只將第一次匹配到的字符串替換成指定的字符串str,返回的時替換後的文本
Pattern pattern=Pattern.compile("\\d+"); String str="chenjiabing2344cal3445"; Matcher matcher=pattern.matcher(str); str=matcher.replaceFirst("陳加兵"); System.out.println(str); //輸出:chenjiabing陳加兵cal3445 /* * str=matcher.replaceAll("陳加兵"); * System.out.println(str) //輸出:chenjiabing陳加兵cal陳加兵 */
捕獲組能夠經過從左到右計算其開括號來編號,編號是從
1
開始的。例如,在表達式((A)(B(C)))
中,存在四個這樣的組:express
((A)(B(C))) (A) (B(C)) (C)
總之在正則表達式中在括號中的就是一個分組,下面用一個實例來理解一下api
Pattern pattern=Pattern.compile("(\\D*)(\\d+)\\s(\\D+)"); Matcher matcher=pattern.matcher("chenjiabingshizuibangde6666 chenjiabign"); if(matcher.find()) { System.out.println("總共匹配到了"+matcher.groupCount()+"個分組"); System.out.println("匹配到整個字符串爲"+matcher.group(0)); System.out.println("匹配到的第一個字符串爲"+matcher.group(1)); System.out.println("匹配到的第二個字符串爲"+matcher.group(2)); System.out.println("匹配到的第三個字符串爲"+matcher.group(3)); }
貪婪與非貪婪模式影響的是被量詞修飾的子表達式的匹配行爲,貪婪模式在整個表達式匹配成功的前提下,儘量多的匹配,而非貪婪模式在整個表達式匹配成功的前提下,儘量少的匹配
通常寫python
爬蟲的時候使用的都是非貪婪模式來匹配
使用了貪婪模式後會儘量匹配更多的字符串,便是到了正則表達式定的末尾可是仍是會繼續向後匹配,看看是否還能匹配,非貪婪模式則是相反,到了正則表達式定義的結束字符就直接中止匹配了
貪婪模式:.*
,.+
非貪婪模式:.*?
,.+?
數組
//使用了貪婪模式,所以當匹配到第一個</div>的時候還要向後面匹配看看是否還能匹配到,因爲後面還有</div>結尾的,所以仍是可以匹配的,所以匹配到的是:陳加兵</div><div>鄭元梅 Pattern pattern=Pattern.compile("<div>(.*)</div>"); //使用了非貪婪模式,所以當匹配到第一個</div>的時候就不向後面匹配了,直接返回了,所以匹配到的是:陳加兵 Pattern pattern1=Pattern.compile("<div>(.*?)</div>"); String str="<div>陳加兵</div><div>鄭元梅</div>"; Matcher matcher=pattern1.matcher(str); if(matcher.find()) { System.out.println(matcher.groupCount()); //1 System.out.println(matcher.group(1)); //輸出匹配到的字符串,此時輸出的是:陳加兵,若是使用貪婪模式輸出的是:陳加兵</div><div>鄭元梅 }