正则表达式在字符串处理中经常使用,关于正则简单的用法相信有一点程序基础的人都懂得一些,这里就不介绍简单基础了。这里主要讲解一下在JAVA中实现了的正则的高级用法-分组与捕获。
对于要重复单个字符,非常简单,直接在字符后卖弄加上限定符即可,例如 a+ 表示匹配1个或一个以上的a,a?表示匹配0个或1个a。这些限定符如下所示:
X ? X ,一次或一次也没有
X * X ,零次或多次
X + X ,一次或多次
X { n } X ,恰好 n 次
X { n ,} X ,至少 n 次
X { n , m } X ,至少 n 次,但是不超过 m 次
但是我们如果要对多个字符进行重复怎么办呢?此时我们就要用到分组,我们可以使用小括号"()"来指定要重复的子表达式,然后对这个子表达式进行重复,例如:(abc)? 表示0个或1个abc 这里一 个括号的表达式就表示一个分组 。
分组可以分为两种形式,捕获组和非捕获组。
捕获组
捕获组可以通过从左到右计算其开括号来编号 。例如,在表达式 ((A)(B(C))) 中,存在四个这样的组:
1 ((A)(B(C)))
2 /A
3 (B(C))
4 (C)
组零始终代表整个表达式
之所以这样命名捕获组是因为在匹配中,保存了与这些组匹配的输入序列的每个子序列。捕获的子序列稍后可以通过 Back 引用 在表达式中使用,也可以在匹配操作完成后从匹配器检索。
Back 引用 是说在后面的表达式中我们可以使用组的编号来引用前面的表达式所捕获到的文本序列(是文本不是正则) 。
例如 ([" ']).* /1 其中使用了分组,/1就是对引号这个分组的引用,它匹配包含在两个引号或者两个单引号中的所有字符串,如,"abc" 或 " ' " 或 ' " ' ,但是请注意,它并不会对" a'或者 'a"匹配。原因上面已经说明,Back引用只是引用文本而不是表达式。
非捕获组
以 (?) 开头的组是纯的非捕获 组,它不捕获文本 ,也不针对组合计进行计数。就是说,如果小括号中以?号开头,那么这个分组就不会捕获文本,当然也不会有组的编号,因此也不存在Back 引用。
在Java中,支持的非捕获组,有如下几种:
(?= X ) X ,通过零宽度的正 lookahead
(?! X ) X ,通过零宽度的负 lookahead
(?<= X ) X ,通过零宽度的正 lookbehind
(?<! X ) X ,通过零宽度的负 lookbehind
这四个非捕获组用于匹配表达式X,但是不包含表达式的文本。
(?=X ) 零宽度正先行断言。仅当子表达式 X 在 此位置的右侧匹配时才继续匹配。例如,/w+(?=/d) 与后跟数字的单词匹配,而不与该数字匹配。此构造不会回溯。
(?!X) 零宽度负先行断言。仅当子表达式 X 不在 此位置的右侧匹配时才继续匹配。例如,例如,/w+(?!/d) 与后不跟数字的单词匹配,而不与该数字匹配 。
(?<=X) 零宽度正后发断言。仅当子表达式 X 在 此位置的左侧匹配时才继续匹配。例如,(?<=19)99 与跟在 19 后面的 99 的实例匹配。此构造不会回溯。
(?<!X) 零宽度负后发断言。仅当子表达式 X 不在此位置的左侧匹配时才继续匹配。例如,(?<!19)99 与不跟在 19 后面的 99 的实例匹配
举例:
上面都是理论性的介绍,这里就使用一些例子来说明一下问题:
1、测试匹配性 (?<!4)56(?=9) 这里的含义就是匹配后面的文本56前面不能是4,后面必须是9组成。因此,可以匹配如下文本 5569 ,与4569不匹配。
2 、提取字符串 提取 da12bka3434bdca4343bdca234bm 提取包含在字符a和b之间的数字,但是这个a之前的字符不能是c,b后面的字符必须是d才能提取。
例如这里就只有3434这个数字满足要求。那么我们怎么提取呢?
首先我们写出提取这个字符串的表达式: (?<!c)a(/d+)bd 这里就只有一个捕获组(/d+)
JAVA代码片段如下:
Pattern p = Pattern.compile( "(?<!c)a(//d+)bd " );
Matcher m = p.matcher( "da12bka3434bdca4343bdca234bm" );
while (m.find()){
System.out.println(m.group( 1 )); //我们只要捕获组1的数字即可。结果 3434
System.out.println(m.group(0)); // 0组是整个表达式,看这里,并没有提炼出(?<!c)的字符 。结果 a3434bd
}
可以看到,非捕获组,最后是不会返回结果的,因为它本身并不捕获文本。
正则表达式功能其实非常强大,这里只是对高级用法的简单探讨。有兴趣的朋友和本人共同讨论。
分享到:
相关推荐
感觉JDK这块不好理解,写了几个例子。求拍求回复。
本文实例讲述了Python正则捕获操作。分享给大家供大家参考,具体如下: 目的: 给表达式 ’10+6/5-4*2′ 中每个运算符左右都加一个空格字符,变成:’10 + 6 / 5 – 4 * 2′ 思路: 分组、捕获、替换 1. 替换字符中...
在正则表达式中,有捕获性分组和非捕获性分组的概念。 捕获性分组是正则表达式中的一个基础概念,使用圆括号()对正则表达式模式的某部分进行分组,这样可以记住这个分组匹配的内容,以便后续可以被引用。例如,在...
与捕获组和非捕获组不同,预查不会消耗字符,也就是说,它们是零宽度的断言。 在PHP的正则表达式中,预查和预查可以使用"?"来简化书写,它们不会影响匹配过程中的字符计数,仅仅是对匹配条件进行额外的判断。例如,...
- **分组与引用**:使用圆括号`()`来定义一个捕获组,并可以通过`\1`、`\2`等引用之前捕获的组。 #### 正则表达式在SQL中的应用 在数据库查询中使用正则表达式可以显著提高查询的灵活性和效率。具体应用场景包括但...
如果正则表达式同时包含普通捕获组和命名捕获组,系统会先为普通捕获组编号,然后再对命名捕获组编号。在这种情况下,命名捕获组仍然可以通过它们的名字进行引用。 捕获组的引用是正则表达式中的一个重要功能。它...
001_正则表达式初体验.wmv ...020_正则表达式非捕获分组之零宽断言.wmv 021_正则表达式非捕获分组之零宽断言2.wmv 022_正则表达式非捕获分组之负向零宽断言.wmv 023_正则表达式之贪婪与懒惰.wmv 024_正则表达式实例应用
除了基础操作,正则表达式还有一些高级特性,如分组(使用圆括号`()`)、非捕获分组(`(?:)`)、反向引用(`\数字`)和条件子表达式(`(?(条件)表达式1|表达式2)`)。这些特性使正则表达式能够处理更复杂的模式匹配...
今天遇到一个正则匹配的问题,忽然翻到有捕获组的概念,手册上也是一略而过,百度时无意翻到C#和Java中有对正则捕获组的特殊用法,搜索关键词有PHP时竟然没有相关内容,自己试了一下,发现在PHP中也是可行的,于是...
正则表达式是处理字符串的强大工具,尤其...综上所述,正则表达式中的捕获组和非捕获组为我们提供了强大的模式匹配和文本处理能力。通过对它们的理解和应用,可以极大地提高我们在处理字符串相关任务时的效率和准确性。
在上一篇文中,我们介绍了关于Python正则表达式的基础,那么在这一篇文章里,我们将总结一下正则表达式关于捕获的用法。下面话不多说,来看看详细的介绍吧。 捕获 捕获和分组在正则表达式中有着密切的联系,一般...
4. **非捕获组**:有时我们希望分组但并不需要保存匹配的结果,这时可以使用非捕获组 `(?:...)`。这种情况下,分组仅用于逻辑运算,不会被当作捕获组对待。 5. **反向引用**:在某些正则表达式引擎中,可以使用反向...
本文实例讲述了JS正则表达式非捕获分组用法。分享给大家供大家参考,具体如下: 最近在看JsonSQL的时候,通过源码中的一段正则表达式,了解到了什么是非捕获分组以及它的使用场景。在js中,正常的捕获分组格式是(XX)...
正则表达式中的捕获组允许我们提取匹配的部分字符串。通常,捕获组通过圆括号定义,例如 `(abc)`。当匹配成功时,这些捕获组会存储在结果数组中,可以通过索引来访问。然而,传统的捕获组无法为每个组提供有意义的...
下面将详细介绍PHP正则表达式中的捕获组与非捕获组。 首先,捕获组是通过圆括号()来定义的,它允许我们将正则表达式中的某个部分视为一个整体。例如,在表达式`/a=(\d+)b=(\d+)c=(\d+)/`中,`\d+`表示一个或多个...