今天在Java中想使用正則表達式來獲取一段文本中的任意字符。因而很隨意得就寫出以下匹配規則:
(.*)
結果運行以後才發現,沒法得到換行以後的文本。因而查了一下手冊,才發現正則表達式中,「.」(點符號)匹配的是除了換行符「\n」之外的全部字符。同時,手冊上還有一句話:要匹配包括 '\n' 在內的任何字符,請使用像 '[.\n]' 的模式。因而我將正則表達式的匹配規則修改以下:
([.\n]*),固然,若是是在java程序中直接寫到話,須要改成([.\\n]*)
結果再次運行程序,發現什麼內容也取不到了。我百思不得其解,又將其修改成以下規則:
([.|\n]*) 以及 ([\n.]*)
結果仍是不行,什麼內容都取不到。看來點符號和換行符卯上勁了~
而後上網一查,雖然沒有查出上述規則究竟是什麼地方出問題了,可是查出了一個解決辦法,通過一試,果真能夠匹配包括換行符在內的任意字符,如下爲正確的正則表達式匹配規則:
([\s\S]*)
同時,也能夠用 「([\d\D]*)」、「([\w\W]*)」 來表示。
在文本文件裏, 這個表達式能夠匹配全部的英文
/[ -~]/
這個表達式能夠匹配全部的非英文(好比中文)
/[^ -~]/
/是VI裏用的. 你在editplus或程序裏不須要/ html
1、小括號()、中括號[]、大括號的區別java
最基本的意思:小括號就是括號內當作一個總體 ,中括號就是匹配括號內的其中一個,大括號就是匹配幾回(可是括號裏變加上其餘字符就有不一樣意思)正則表達式
(1)小括號():匹配小括號內的字符串,能夠是一個,也能夠是多個,常跟「|」(或)符號搭配使用,是多選結構的數組
示例1:string name = "way2014"; regex:(way|zgw) result:結果是能夠匹配出way的,由於是多選結構,小括號是匹配字符串的spa
示例2:string text = "123456789"; regex:(0-9) result:結果是什麼都匹配不到的,它只匹配字符串"0-9"而不是匹配數字, [0-9]這個字符組纔是匹配0-9的數字code
(2)中括號[]:匹配字符組內的字符,好比我們經常使用的[0-9a-zA-Z.*?!]等,在[]內的字符都是字符,不是元字符,好比「0-9」、「a-z」這中間的「-」就是鏈接符號,表示範圍的元字符,若是寫成[-!?*(]這樣的話,就是普通字符htm
示例1: string text = "1234567890"; regex:[0-9] result:結果是能夠匹配出字符串text內的任意數字了,像上邊的【或符號「|」在字符組內就是一個普通字符】對象
示例2:string text = "a|e|s|v"; regex:[a|e|s] result:結果就是匹配字符a、e、|三個字符,這個跟(a|e|s)有區別的,區別就是(a|e|s)匹配的是a、e、s三個字符的隨意一個,三個中的任意一個,這是的|是元字符blog
(3)大括號{}:匹配次數,匹配在它以前表達式匹配出來的元素出現的次數,{n}出現n次、{n,}匹配最少出現n次、{n,m}匹配最少出現n次,最多出現m次字符串
舉例詳細介紹 例如:
{n}
n是一個非負整數。匹配肯定的n次。例如,「o{2}」不能匹配「Bob」中的「o」,可是能匹配「food」中的兩個o。
{n,}
n是一個非負整數。至少匹配n次。例如,「o{2,}」不能匹配「Bob」中的「o」,但能匹配「foooood」中的全部o。「o{1,}」等價於「o+」。「o{0,}」則等價於「o*」。
{n,m}
m和n均爲非負整數,其中n<=m。最少匹配n次且最多匹配m次。例如,「o{1,3}」將匹配「fooooood」中的前三個o。「o{0,1}」等價於「o?」。請注意在逗號和兩個數之間不能有空格。
?
當該字符緊跟在任何一個其餘限制符(*,+,?,{n},{n,},{n,m})後面時,匹配模式是非貪婪的。非貪婪模式盡
可能少的匹配所搜索的字符串,而默認的貪婪模式則儘量多的匹配所搜索的字符串。例如,對於字符串「oooo」,「o+?」將匹配單個「o」,而「o+」將匹配全部「o」。
在正則匹配中,通常將匹配的字符串稱爲分組 0,按括號出現的順序依次將其內容稱爲分組 一、分組 2……例如正則 /(a)(b)/ 匹配字符串 "ab",則分組 0 爲 "ab",分組 1 爲 "a",分組 2 爲 "b"。執行正則匹配 /(a)(b)/.exec("ab") 的結果 ["ab", "a", "b"] 就是各個分組構成的字符串。若是去掉圓括號就沒有分組 一、分組2……結果就是隻包含分組 0 即匹配字符串的長度爲 1 的數組 ["ab"]。
這裏順便說一下貪婪和非貪婪的匹配原理(注:JAVA默認是貪婪模式):
a) 若是是貪婪匹配模式則匹配結果爲最長匹配,正則表達式引擎會一直匹配到字符串最後,當匹配爲false時,經過回溯的方式,倒退找到倒數第一個匹配位置,返回匹配結果
Java代碼
String str = "(a)(b)(c)(d)(e)"; String regex = "\\(.*\\)"; Pattern pattern = Pattern.compile(regex); Matcher matcher = pattern.matcher(str); System.out.println("replace: "+str.replaceAll(regex, "O")); while (matcher.find()) { System.out.println("matcher: " + matcher.group(0)); }
輸出:
replace:O
matcher: (a)(b)(c)(d)(e)
b) 若是是非貪婪匹配模式則匹配結果爲最短匹配,正則表達式引擎會匹配到符合pattern的末尾位置那個字符,而後再日後走一步,發現匹配爲false, 又回溯到找到回退的最近一個匹配爲true的位置,返回結果。
能夠經過調用 matcher 對象的 groupCount 方法來查看錶達式有多少個分組。groupCount 方法返回一個 int 值,表示matcher對象當前有多個捕獲組。還有一個特殊的組matcher.group(0),它老是表明整個表達式。該組不包括在 groupCount 的返回值中。
Java代碼
String str = "(a)(b)(c)(d)(e)"; String regex = "\\(.*?\\)"; Pattern pattern = Pattern.compile(regex); Matcher matcher = pattern.matcher(str); System.out.println("replace: "+str.replaceAll(regex, "O")); while (matcher.find()) { System.out.println("matcher: " + matcher.group(0)); int count = matcher.groupCount(); //查看每一個匹配串的括號中的內容 for(int i = 0;i<=count;i++){ System.out.print(i+" "); System.out.println(matcher.group(i)); } }
輸出:
replace: OOOOO
matcher: (a)
matcher: (b)
matcher: (c)
matcher: (d)
matcher: (e)