`

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

阅读更多
针对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://topic.csdn.net/u/20080503/01/3c82b040-43b9-4b44-847d-07b366285957.html
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"。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后。
分享到:
评论

相关推荐

    java_zhengze.rar_正则表达式_正则表达式 java

    本资料"java_zhengze.rar"提供了对Java正则表达式的详细讲解,包括基本概念、元字符、预定义字符类以及各种匹配操作,对于Java开发者来说是一份非常实用的学习资源。 首先,我们来了解一下正则表达式的基石——元...

    JAVA正则表达式实例教程.pdf

    ### JAVA正则表达式实例教程知识点详述 #### 一、正则表达式的定义与特点 **1.1 正则表达式是什么?** - 正则表达式(Regular Expression)是一种模式匹配语言,用于文本搜索和替换。它提供了一种简洁而灵活的方式...

    JAVA正则表达式实例教程

    ### JAVA正则表达式实例教程知识点详述 #### 一、正则表达式的定义与特点 **1.1 正则表达式是什么?** - **定义:** 正则表达式(Regular Expression)是一种用于匹配字符串中字符组合的工具,广泛应用于搜索、...

    java 正则表达式 perl5规范 jakarta-oro.jar

    Java正则表达式是Java编程语言中用于处理字符串的强大工具,它遵循Perl 5规范,提供了灵活且功能丰富的模式匹配能力。Jakarta ORO(Oracle RegEx)库是Apache软件基金会的一个项目,它是一个高性能的Java正则表达式...

    正则表达式(java).rar

    5. **正则表达式的特殊构造** - **选择**:`|`表示或,如`cat|dog`匹配"cat"或"dog"。 - **分支截断**:`(?|...)`用于创建非捕获分组,优化匹配性能。 - **惰性匹配**:`.*?`匹配尽可能少的字符,避免贪婪匹配。 ...

    精通正则表达式中文版英文版_中文版为扫描版

    在正则表达式的世界里,基础概念包括字符类(如匹配任何数字[\d])、量词(匹配0次或多次*,1次或多次+,至少n次{n}等)、分组与捕获(使用括号()来定义一个子模式)、预查(用^符号否定预查,如[^abc]匹配非abc的...

    正则表达式教程合集(各种语言的,超全)

    正则表达式还支持更多的高级特性,如非捕获组 `(?:...)`、选择 `(a|b)`、重复 `{n}`、`{n,}`、`{n,m}`、预查 `(?=...)` 和否定预查 `(?!...)`。 通过这些教程,你可以深入理解正则表达式的核心概念,并学习如何在...

    使用正则表达式拆分字符串

    - **效率**:如果正确构造,正则表达式拆分可以快速有效地处理大量文本。 - **复杂性**:对于包含特殊字符和结构的字符串,正则表达式提供了更强大的处理能力。 5. 注意事项 - 当正则表达式中包含贪婪模式时,...

    java正则表达式20页详细java正则表达式讲义课件可做教学用

    本文档详细介绍了Java正则表达式的各种基础知识,包括基本概念、限定符、特殊匹配符、边界匹配符以及分组构造等内容。通过这些知识点的学习,读者可以更好地理解和运用Java中的正则表达式来解决实际问题。正则表达式...

    正则表达式验证器,验证常用的编程语言的正则表达式

    在编程中,正确构造和理解正则表达式至关重要,因为它们能帮助我们高效地处理字符串数据。"正则表达式验证器"是一个实用工具,它允许用户输入自定义的正则表达式,并通过提供测试用例来验证该表达式的正确性。 这个...

    JAVA的正则表达式.doc

    以下是对Java正则表达式的关键知识点的详细解释: 1. **英文句点符号**:`.` 代表任意单个字符,除了换行符。例如,表达式 "t.o" 可以匹配 "tno","t#o","teo" 等,但不能匹配 "tnno","to" 或 "Tno"。 2. **方...

    [精通正则表达式(第三版)].(美)佛瑞德.扫描版(modify).pdf

    读者在阅读本书时应该特别关注正则表达式的设计原理、各种元字符和特殊构造的使用技巧,以及在实际编程中如何高效地运用正则表达式解决实际问题。同时,学习如何避免常见的错误和性能陷阱,提高编程效率和代码质量。

    正则表达式 正则表达式 正则表达式

    - 在JavaScript、Python、Java、C#等编程语言中,正则表达式都有内置的支持,提供了构造、匹配、替换、查找等功能。 8. **实例应用**: - 验证邮箱地址:`/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/` ...

    Java正则表达式教程

    Java正则表达式教程是为那些想要深入了解Java编程语言中正则表达式使用方法的初学者准备的。正则表达式(Regular Expression)是一种强大的文本处理工具,它用于模式匹配、搜索、替换等操作,广泛应用于字符串处理和...

    精通正则表达式(第三版)简体中文.pdf

    3. **后向引用与非捕获组**:后向引用允许在正则表达式中引用前面分组的内容,而非捕获组则可以在不影响整体分组结构的情况下定义一个子模式。 4. **高级特性**:如lookaround(前瞻后顾)、条件表达式、嵌套结构等...

    java 正则表达式详解

    Java正则表达式是Java编程语言中用于处理字符串的强大工具,它允许程序员高效地进行文本匹配、搜索和替换。在Java中,正则表达式主要通过`java.util.regex`包来实现。本教程将深入探讨Java正则表达式的基础、核心...

    java \javascript 正则表达式

    正则表达式是一种强大的文本处理工具,用于在Java和JavaScript中进行字符串匹配、搜索、替换等操作。在编程中,正则表达式是处理文本数据不可或缺的一部分,它们使用特殊的字符序列来定义一个模式,该模式可以用来...

Global site tag (gtag.js) - Google Analytics