今天在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)