以下内容均为个人理解,方便后续复习用博客整理起来,如果有误,还望指正。。。。(以下均为java在eclipse中的正则表达式)
在java正则表达式中,( )是分组的意思,依旧是所谓的捕获组。每一个( )代表着一个group,该组是通过从左至右计算其括号来编号。
一个经典的例子:
在表达式((A)(B(C))),有四个这样的组:
- ((A)(B(C)))
- (A) 可以看出,这个分组就是按照括号从左至右计算得来的
- (B(C))
- (C)
可以通过调用 matcher 对象的 groupCount 方法来查看表达式有多少个分组。groupCount 方法返回一个 int 值,表示matcher对象当前有多个捕获组。
还有一个特殊的组(group(0)),它总是代表整个表达式。该组不包括在 groupCount 的返回值中。
到此,我对()分组的探究并没有停止,在看了不少博客之后,我发现分组还能够通过引用来简化表达式,而引用的方式是(1或者$1)。
总结下来分组 的作用(借鉴别人的博客):
1.将某些规律看成是一组,然后进行组级别的重复,可以得到意想不到的效果。
2.分组之后,可以通过后向引用简化表达式(1 或者$1)。
分组举列
先来看第一个作用,对于IP地址的匹配,简单的可以写为如下形式(eclipse中java正则):
String pattern = "(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})";
从这个 我们可以看出,这里有五个group,group(0)、group(1)、group(2)、group(3)、group(4),并且这几个分组的正则表达式都是一样的。我们可以对上述正则表达式进行简化。结果如下:
String pattern = "(\d{1,3})(\.(\d{1,3})){3}";
这个表达式的意思就是把IP地址
再来看第二个作用,就拿匹配<title>hello</title>标签来说,简单的正则可以这样写:
<title>.*</title>
可以看出,上边表达式中有两个title,完全一样,其实可以通过分组简写。表达式如下:
<(title)>.*</1> eclipse中是<(title)>.*</\1>
对于分组而言,整个表达式永远算作第0组,在本例中,第0组是<(title)>.*</\1>,然后从左到右,依次为分组编号,因此,(title)是第1组。看下面的代码
public class Title {public static void main(String[] args) {String title="<title>hello</title>";String pattern = "<(title)>.*</\1>";Pattern p=Patternpile(pattern);//Pattern p=Patternpile(pattern1);Matcher m=p.matcher(title);if(m.find()==true) {boolean b=m.matches();System.out.println(b);System.out.up(0));System.out.up(1));System.out.up(2));}}
}
会在控制台打印如下:
错误提示是没有组2,因为在这个代码中就只有(title)这一个组。
注意:
用1这种语法,可以引用某组的文本内容,但不能引用正则表达式。
例如刚刚的IP地址正则表达式为(\d{1,3})(\.(\d{1,3})){3},里边的\.(\d{1,3})重复了三次,如果利用后向引用简化,表达式如下:
String pattern2 = "(\d{1,3})(\.\1){3}";
经过实际测试,会发现这样写是错误的,为什么呢?
后向引用,引用的仅仅是文本内容,而不是正则表达式!
也就是说,组中的内容一旦匹配成功,后向引用,引用的就是匹配成功后的内容,引用的是结果,而不是表达式。
因此,(\d{1,3})(\.\1){3}这个表达式实际上匹配的是四个数都相同的IP地址,比如:225.225.225.225。代码:
public class IP {public static void main(String[] args) {String ip="225.225.225.225";
// String pattern = "(\d{1,3})(\.(\d{1,3})){3}";
// String pattern1 = "(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})";String pattern2 = "(\d{1,3})(\.\1){3}";Pattern p=Patternpile(pattern2);Matcher m=p.matcher(ip);if(m.find()==true) {boolean b=m.matches();System.out.println(b);System.out.up(0));}}
}
控制台打印结果:
正则真的玄妙,一个小小的()分组都够研究半天了,估计是我太菜了。。。。。
注:在进一步学习后,遇到这个问题:
在使用?<=和?=时,例如:(?<=(href=")).*(?=(">))。
按照之前的分析,此时的group(1)是(?<=(href=")),group(2)应该是(href="),其实并不是这样的,在正则表达式中(?<=pattern)是一个字符。正确的group(1)是(href=")。
贴一个例子:
public class UseGhd {public static void main(String[] args) {//(?<=(href=")).{1,200}(?=(">))String s="<br/>您好,非常好,很开心认识你rn" + "<br/><a target=_blank href="www.baidu">百度一下</a>百度才知道rn" + "<br/><a target=_blank href="/view/fafa.htm">发发</ a>最佳帅哥rn" + "<br/><a target=_blank href="/view/lili.htm">丽丽</ a>最佳美女rn" + "<br/>";String pattern="(?<=(href=")).*(?=(">))";Pattern p=Patternpile(pattern);//Pattern p=Patternpile(pattern1);Matcher m=p.matcher(s);while(m.find()) {//System.out.println(m);System.out.up(0));System.out.up(1));System.out.up(2));}String s1="dog";String pattern1="((.)(.(.)))";Pattern p1=Patternpile(pattern1);Matcher m1=p1.matcher(s1);while(m1.find()) {//System.out.println(m);System.out.up(0));System.out.up(1));System.out.up(2));System.out.up(3));System.out.up(4));}}
}
结果:
其中道理 慢慢捋一捋就能知道。。。。
本文发布于:2024-02-03 03:40:21,感谢您对本站的认可!
本文链接:https://www.4u4v.net/it/170690282148415.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |