首页 > 编程语言 >java 正则表达式 非捕获组(特殊构造)

java 正则表达式 非捕获组(特殊构造)

时间:2023-08-27 12:02:15浏览次数:39  
标签:字符 匹配 正则表达式 lookahead 捕获 Windows java idmsux


针对Java API文档中的正则表达式关于特殊构造(非捕获组)的说明,例如:
1.(?:X) X, as a non-capturing group
2.(?idmsux-idmsux)  Nothing, but turns match flags on - off
3.(?idmsux-idmsux:X)   X, as a non-capturing group with the given flags on - off
4.(?=X) X, via zero-width positive lookahead
5.(?!X) X, via zero-width negative lookahead
6.(?<=X) X, via zero-width positive lookbehind
7.(?<!X) X, via zero-width negative lookbehind
8.(?>X) X, as an independent, non-capturing group

1.(?:X) X,作为非捕获组
2.(?idmsux-idmsux) Nothing,但是将匹配标志由 on 转为 off
3.(?idmsux-idmsux:X) X,作为带有给定标志 on - off 的非捕获组
4.(?=X) X,通过零宽度的正 lookahead
5.(?!X) X,通过零宽度的负 lookahead
6.(?<=X) X,通过零宽度的正 lookbehind
7.(?<!X) X,通过零宽度的负 lookbehind
8.(?>X) X,作为独立的非捕获组

现在主要是针对以上8个Regular Expression的Meta Data进行研究:
我们都知道以(?开头,)结尾的都称之为非捕获组,在匹配完成后在内存中不保留匹配到的字符。
1、(?:X) X,作为非捕获组
与捕获组 ( ) 的意思一样也是将其作为一组进行处理,与捕获组的区别在于不捕获匹配的文本,
仅仅作为分组。
比如:要匹配 123123 这个,就可以写为 (123)\1 使用反向引用,这时只能用捕获组,在匹配
123 后会保留在内存中,便于反向引用,而 (?:123) 在匹配完后则不会保留,区别仅在于此。

2、(?idmsux-idmsux) Nothing,但是将匹配标志i d m s u x on - off
用于标志匹配,比如:表达式 (?i)abc(?-i)def 这时,(?i) 打开不区分大小写开关,abc 匹配
不区分大小地进行匹配,(?-i) 关闭标志,恢复不区分大小写,这时的 def 只能匹配 def

3、(?idmsux-idmsux:X) X,作为带有给定标志 i d m s u x on - off
与上面的类似,上面的表达式,可以改写成为:(?i:abc)def,或者 (?i)abc(?-i:def)

4、(?=X) X,通过零宽度的正 lookahead
5、(?!X) X,通过零宽度的负 lookahead
(?=X) 表示当前位置(即字符的缝隙)后面允许出现的字符,比如:表示式 a(?=b),在字符串为
ab 时,可能匹配 a,后面的 (?=b) 表示,a 后面的缝隙,可以看作是零宽度。
(?!X) 表示当前位置后面不允许出现的字符

6、(? <=X) X,通过零宽度的正 lookbehind
7、(? <!X) X,通过零宽度的负 lookbehind
这两个与上面两个类似,上面两个是向后看,这个是向前看

8、(?>X) X,作为独立的非捕获组
匹配成功不进行回溯,这个比较复杂,也侵占量词“+”可以通用,比如:\d++ 可以写为 (?>\d+)。

我认为,第1、2、3点比较好理解,4、5、6、7看类懂,还是用示例来说明:从“aacabab”找a,且后面只允许出现b。代码如下:
Pattern p = Pattern.compile("a(?=b)");
Matcher m = p.matcher("aacabab");
while(m.find()) {
    System.out.println(m.group()+", start="+m.start()+", end="+m.end());
}

运行结果:
a, start=3, end=4
a, start=5, end=6

个人理解:在(?=b)这个“式”后面允许出现b,且这个“式”不占正则表达式位置(所谓0宽度),lookahead 的意思是b字符的前面,它前面紧接着是a,也就是a后面出现b。

8比较难理解, 推荐的链接找到答案:
http://www.regular-expressions.info/atomic.html

其中说的示例:来看 /\b(integer|insert|in)\b/ 匹配 integers 过程,第一个,当integer\b匹配到s时失败,然后字符串(integers)会回溯到i,再接着第二个(insert)去匹配。而把模式写成 /\b(?>integer|insert|in)\b/ 在刚才的第一个匹配失败,字符串(integers)不会回溯了,也不会有第二个去匹配了,所有速度会快一点点。

但是写 (?>X) 这种式子时要注意,是从左到右看的。/\b(?>integer|insert|in)\b/ ,与 /\b(?>in|integer|insert)\b/ 去匹配 insert,结果会不一样,前者可以匹配到,后者不能,什么原因自己分析下。一但匹配失败就会跳过,所以应该长的写在表达式前面。

参考:

http://www.regular-expressions.info/atomic.html

java正则表达式的(?:X),(?=X),(?!X),(?<=X),(?<!X),(?>X)的含义

(?:pattern) 匹配 pattern 但不获取匹配结果,也就是说这是一个非获取匹配,不进行存储供以后使用。这在使用 "或" 字符 (|) 来组合一个模式的各个部分是很有用。例如, 'industr(?:y|ies) 就是一个比 'industry|industries' 更简略的表达式。

(?=pattern) 正向预查,在任何匹配 pattern 的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。例如, 'Windows (?=95|98|NT|2000)' 能匹配 "Windows 2000" 中的 "Windows" ,但不能匹配 "Windows 3.1" 中的 "Windows"。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始。

(?!pattern) 负向预查,在任何不匹配Negative lookahead matches the search string at any point where a string not matching pattern 的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。例如'Windows (?!95|98|NT|2000)' 能匹配 "Windows 3.1" 中的 "Windows",但不能匹配 "Windows 2000" 中的 "Windows"。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后。

标签:字符,匹配,正则表达式,lookahead,捕获,Windows,java,idmsux
From: https://blog.51cto.com/u_16237557/7252163

相关文章

  • 《突击面试》JavaPub版
    突击面试题汇总持续更新中...《突击面试》(点击阅读)【JVM】10道不得不会的JVM面试题(点击阅读)10道不得不会的Zookeeper面试题(点击阅读)10道不得不会的MyBatis面试题(点击阅读)10道不得不会的缓存面试题【缓存】(点击阅读)10道不得不会的JavaEE(点击阅读)【Kafka】10......
  • JavaScript的变量提升
    参考资料:https://time.geekbang.org/column/article/126339目录变量提升变量形式声明的函数变量提升导致的问题变量被覆盖变量不被销毁避开变量提升引入let和const关键字块级作用域变量提升是在代码执行时,把变量和函数的声明部分提升到代码开头的行为,变量被提升后,会被默认设置......
  • Java使用Jsch执行Shell命令
    JSch是SSH2的纯Java实现。JSch允许您连接到sshd服务器并使用端口转发,X11转发,文件传输等,您可以将其功能集成到您自己的Java程序中。JSch获得BSD格式许可证。最初,我们开发这些东西的动机是允许我们的纯JavaX服务器WiredX的用户享受安全的X会话。所以,我们的努力主要是为了实现用......
  • 使用 Java 生成二维码图片
    0x01准备(1)软件版本IntelliJIDEA2023.1.3JDK18Tomcat10.1.11Maven3.8.6(2)技术栈servletzxing谷歌项目生成黑白二维码并可以附上logoqrcodegithub开源项目基于并拓展zxing(3)创建项目创建空项目在菜单栏-文件-项目结构中设置JDK及语言级别......
  • JavaScript中的不可变原始值和可变对象引用
    在JavaScript中,原始值(undefined、null、布尔值、数字和字符串)与对象(包括数组和函数)之间存在着根本的区别。原始值是不可变的,意味着它们的值无法改变。这对于数字和布尔值很容易理解:修改它们的值是没有意义的。然而,对于字符串来说,这可能会稍微不太直观。由于字符串类似于字符数组,可......
  • Java实现数据导出到excel文件
    Java实现数据导出到excel文件使用的依赖:Apache提供的poi包首先导入依赖<dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>5.2.2</version></dependency>核心实现//创建一个工作簿,也就是Excel......
  • java中的图算法
    Java中有许多用于图算法的库和框架。下面是一些常见的图算法及其在Java中的实现方式:广度优先搜索(BFS):BFS用于在图中搜索最短路径。在Java中,可以使用LinkedList和HashSet来实现BFS算法。深度优先搜索(DFS):DFS用于在图中搜索路径或查找连通分量。在Java中,可以使用递归或栈来实现DFS算法......
  • Java实现数据导出到excel文件
    Java实现数据导出到excel文件使用的依赖:Apache提供的poi包首先导入依赖<dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>5.2.2</version></dependency>核心实现//创建一个工作簿,也就是Excel......
  • 基于JavaWeb的游戏信息管理系统设计与实现-计算机毕业设计源码
    摘要随着信息技术的发展,基于web模式的管理系统逐渐普及,网上查找信息是目前广受欢迎的模式。基于JavaWeb的游戏信息管理系统可以适应现代化快节奏的游戏方式,满足各类人群足不出户的在线查找游戏,利用基于JavaWeb的游戏信息管理系统可以获取游戏的排名信息,并可以记录个人的游戏数据,......
  • 基于Java的学生管理系统-计算机毕业设计源码+LW文档
    摘 要计算机信息技术的迅猛发展,改变了人们的生产生活方式。越来越多的教务管理使用管理系统进行管理,用来提高管理效率。在传统的教学管理中,往往通过大量的人力和物力进行管理,通过手工记录课程信息,统计科目资料。这种传统的管理方法容易出错,而且不能适应现代化、信息化的发展过程......