不知道 ? 为什么是贪婪!名字起的怪怪的,我这里用UML的角度解释下 ?就是 0或者1
+→[1,无穷]
*→[0,无穷]
?→[0,1]
*,+,? 都是贪婪模式 (单一的量词都是贪婪模式,单独的*,?,+,{})尽可能多的匹配
*?,+?,??都是懒惰模式
*+,++,?+ 这些叫占有优先量词 (占有优先要是理解不透彻就先别用了容易出问题,主要用于提高效率)
贪婪模式是尽可能多的匹配
懒惰模式是尽可能少的匹配,满足下限就行
占有优先是匹配的字符不会吐出来
例子:{
正则 :abc++1 目标字符串:absadfasdabcabc1
c+要求尽可能多的匹配c
先找到第一个abc,然后下一个字符是a,不是c所以c++匹配结束了,abc++1
但是之后要求有1
这时候发现a<>1,所以这次查找也失败了,正则开始从下一个位置查找,也就是bcabc1从b这开始b不是a,结束,cabc1c不是a,结束,abc1发现a了abc++1往下匹配abc都能对应上了,匹配结束
}
举个例子reg=.{1,3}+1
str=xy1y
.{1,3}这里.后面是量词,量词后面跟着+ 所以是占有优先
解释:.{1,3} 尽可能多的匹配,这样匹配了前三个字符xy1,而.{1,3}+后面还有个1
由于占有优先,因此不会吐出1,以至于匹配不到
插入下 正则 “回溯” 执行{
字符串: ab1c1 正则:.*1
.*会一直匹配到最后 .*1 找完.* 然后再找1 最后没有字符了(.一般不匹配\n,\r),不行,之前匹配的东西就得吐出来一个( 从右向左 反吐) 看看是不是1,直到找到1为止
例子 .*1 里的 .* 匹配 ab1cd1ef 的时候 会走到最后 ,然后 到 .*1 里的 1 ,这样就会先吐出 f 再吐出 e 再吐出 1 发现 可以,允许匹配,终止跳出 ,这里将不考虑ab后面的l了
}
回归占有优先正题:占有优先就是匹配了的字符不再吐出来,没有了回溯{
例子:字符串aabbccddccbb正则:bc++c
第一个b后面不是c,不行
第二个b后面可以bc(吃掉一个c)
于是这部分匹配了
bc+继续找c(吃掉一个c)
bcc匹配到这3个字符
现在bc++
后面还有一个加号
那就是说c+匹配的东西不会再还给你了
bc++c后面这个c,就找不到对应的c了
所以此次匹配失败
然后从aabb后面的c再开始按照规则查找
总结下:字符++字符(两个字符一样) 肯定是什么都匹配不到的
}
强制与非强制区别: 找到0个 也通过,?*都不是强制的
?和*,既然都可以取到,那正则在没有找到要匹配的元素的时候
那就令?=0,*=0就可以了,这样就能成功匹配了
----------------------------------
\b是单词开始结束的标记
abcd \babc 就是说 一个单词以abc开始 abc\b 就是说一个单词以abc结束
不在[]中,^表示开始
^和-,只有在[]里面放在最开始才有特殊含义,[^]表示非
-在开头的话,-就表示他自己 ,在中间才是特殊字符 比如 [a-z]
[]里面相当于| 或
http://gskinner.com/RegExr 测试
\b(\w+)\b(\s*\1)+ 匹配重复出现单词 asd asd aaa asd asd asd ddww ddww aaddweeas asd sd sd ee ee a a
\b(\w+)\b一个单词之后,后面会有空白断开
所以要\s,空白之后要求还是前面的单词,所以\1
多个就是在空白,再\1
+→[1,无穷]
*→[0,无穷]
?→[0,1]
*,+,? 都是贪婪模式 (单一的量词都是贪婪模式,单独的*,?,+,{})尽可能多的匹配
*?,+?,??都是懒惰模式
*+,++,?+ 这些叫占有优先量词 (占有优先要是理解不透彻就先别用了容易出问题,主要用于提高效率)
贪婪模式是尽可能多的匹配
懒惰模式是尽可能少的匹配,满足下限就行
占有优先是匹配的字符不会吐出来
例子:{
正则 :abc++1 目标字符串:absadfasdabcabc1
c+要求尽可能多的匹配c
先找到第一个abc,然后下一个字符是a,不是c所以c++匹配结束了,abc++1
但是之后要求有1
这时候发现a<>1,所以这次查找也失败了,正则开始从下一个位置查找,也就是bcabc1从b这开始b不是a,结束,cabc1c不是a,结束,abc1发现a了abc++1往下匹配abc都能对应上了,匹配结束
}
举个例子reg=.{1,3}+1
str=xy1y
.{1,3}这里.后面是量词,量词后面跟着+ 所以是占有优先
解释:.{1,3} 尽可能多的匹配,这样匹配了前三个字符xy1,而.{1,3}+后面还有个1
由于占有优先,因此不会吐出1,以至于匹配不到
插入下 正则 “回溯” 执行{
字符串: ab1c1 正则:.*1
.*会一直匹配到最后 .*1 找完.* 然后再找1 最后没有字符了(.一般不匹配\n,\r),不行,之前匹配的东西就得吐出来一个( 从右向左 反吐) 看看是不是1,直到找到1为止
例子 .*1 里的 .* 匹配 ab1cd1ef 的时候 会走到最后 ,然后 到 .*1 里的 1 ,这样就会先吐出 f 再吐出 e 再吐出 1 发现 可以,允许匹配,终止跳出 ,这里将不考虑ab后面的l了
}
回归占有优先正题:占有优先就是匹配了的字符不再吐出来,没有了回溯{
例子:字符串aabbccddccbb正则:bc++c
第一个b后面不是c,不行
第二个b后面可以bc(吃掉一个c)
于是这部分匹配了
bc+继续找c(吃掉一个c)
bcc匹配到这3个字符
现在bc++
后面还有一个加号
那就是说c+匹配的东西不会再还给你了
bc++c后面这个c,就找不到对应的c了
所以此次匹配失败
然后从aabb后面的c再开始按照规则查找
总结下:字符++字符(两个字符一样) 肯定是什么都匹配不到的
}
强制与非强制区别: 找到0个 也通过,?*都不是强制的
?和*,既然都可以取到,那正则在没有找到要匹配的元素的时候
那就令?=0,*=0就可以了,这样就能成功匹配了
----------------------------------
\b是单词开始结束的标记
abcd \babc 就是说 一个单词以abc开始 abc\b 就是说一个单词以abc结束
不在[]中,^表示开始
^和-,只有在[]里面放在最开始才有特殊含义,[^]表示非
-在开头的话,-就表示他自己 ,在中间才是特殊字符 比如 [a-z]
[]里面相当于| 或
http://gskinner.com/RegExr 测试
\b(\w+)\b(\s*\1)+ 匹配重复出现单词 asd asd aaa asd asd asd ddww ddww aaddweeas asd sd sd ee ee a a
\b(\w+)\b一个单词之后,后面会有空白断开
所以要\s,空白之后要求还是前面的单词,所以\1
多个就是在空白,再\1
String str=" asd asd aaa asd asd asd ddww ddww aaddweeas asd sd sd ee ee a a 啊 啊 啊";
Pattern pa = Pattern.compile("\\b(\\w+)\\b(\\s*\\1)+");
Matcher ma = pa.matcher(str);
while(ma.find()){
System.out.println(ma.group());
}