`

分组 捕获 引用

    博客分类:
  • php
 
阅读更多

分组 捕获 引用

             转自:http://blog.csdn.net/hehe9737/article/details/7792653

对于要重复单个字符,非常简单,直接在字符后卖弄加上限定符即可,例如 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))) 中,存在四个这样的组:

((A)(B(C)))\A(B(C))(C)

组零始终代表整个表达式

之所以这样命名捕获组是因为在匹配中,保存了与这些组匹配的输入序列的每个子序列。捕获的子序列稍后可以通过 Back 引用在表达式中使用,也可以在匹配操作完成后从匹配器检索。

Back 引用是说在后面的表达式中我们可以使用组的编号来引用前面的表达式所捕获到的文本序列(是文本不是正则)。

例如 ([" ']).* \1 其中使用了分组,\1就是对引号这个分组的引用,它匹配包含在两个引号或者两个单引号中的所有字符串,如,"abc" 或 " ' " 或 ' " ' ,但是请注意,它并不会对" a'或者 'a"匹配。原因上面已经说明,Back引用只是引用文本而不是表达式。

非捕获组

以 (?) 开头的组是纯的非捕获 组,它不捕获文本,也不针对组合计进行计数。就是说,如果小括号中以?号开头,那么这个分组就不会捕获文本,当然也不会有组的编号,因此也不存在Back 引用。

在Java中,支持的非捕获组,有如下几种:

1.(?=X)X,通过零宽度的正 lookahead(?!X)X,通过零宽度的负 lookahead(?<=X)X,通过零宽度的正 lookbehind(?<!X)X,通过零宽度的负 lookbehind这四个非捕获组用于匹配表达式X,但是不包含表达式的文本。(?=X )零宽度正先行断言。仅当子表达式 X 在此位置的右侧匹配时才继续匹配。例如,\w+(?=\d) 与后跟数字的单词匹配,而不与该数字匹配。此构造不会回溯。

    

2.(?!X)零宽度负先行断言。仅当子表达式 X 不在此位置的右侧匹配时才继续匹配。例如,例如,\w+(?!\d) 与后不跟数字的单词匹配,而不与该数字匹配。

 

3.(?<=X)零宽度正后发断言。仅当子表达式 X 在此位置的左侧匹配时才继续匹配。例如,(?<=19)99 与跟在 19 后面的 99 的实例匹配。此构造不会回溯。

 

4.(?<!X)零宽度负后发断言。仅当子表达式 X 不在此位置的左侧匹配时才继续匹配。例如,(?<!19)99 与不跟在 19 后面的 99 的实例匹配

                 (?<!19)mm代表   mm在19的左边时继续匹配  ;如mm19匹配




举例:

上面都是理论性的介绍,这里就使用一些例子来说明一下问题:

1、测试匹配性 (?<!4)56(?=9) 这里的含义就是匹配后面的文本56前面不能是4,后面必须是9组成。因此,可以匹配如下文本 5569 ,与4569不匹配。

2 、提取字符串 提取 da12bka3434bdca4343bdca234bm 提取包含在字符a和b之间的数字,但是这个a之前的字符不能是c,b后面的字符必须是d才能提取。

例如这里就只有3434这个数字满足要求。那么我们怎么提取呢?

首先我们写出提取这个字符串的表达式: (?<!c)a(\d+)bd 这里就只有一个捕获组(\d+)

JAVA代码片段如下:

  1. Pattern p = Pattern.compile("(?<!c)a(");
  2. Matcher m = p.matcher("da12bca3434bdca4343bdca234bm");
  3. while(m.find()){
  4. System.out.println(m.group(1)); //我们只要捕获组1的数字即可。结果 3434
  5. System.out.println(m.group(0)); // 0组是整个表达式,看这里,并没有提炼出(?<!c)的字符 。结果 a3434bd
  6. }

可以看到,非捕获组,最后是不会返回结果的,因为它本身并不捕获文本。

最后用了两种方法解决:

解法一:比较笨的方法,没有使用非捕获组:

Pattern p = Pattern.compile("<(.*)>.*</\\1>");……

Matcher m = p.matcher(line);
HashSet setstr = new HashSet();
while( m.find()){
if( !setstr.contains(m.group(1)) && !setstr.isEmpty()){
//这里的line就是符合要求的内容

解法二:使用非捕获组

Pattern p = Pattern.compile("<(.*)>.*</\\1>.*<(?!\\1)");
一个正则表达式就可解决。

再次印证了正则表达式的重要性。

 

分享到:
评论

相关推荐

    JavaScript正则表达式的分组匹配详解

    分组 下面的正则表达式可以匹配kidkidkid: /kidkidkid/ 而另一种更优雅的写法是: /(kid){3}/ 这里由圆括号包裹的一个小整体称为分组。...一个分组中,可以有多个候选表达式,用|分隔: ...捕获与引用 被

    PHP中的正则表达式实例详解

    在正则中分组很有用,可以定义子模式,然后可以通过后向引用来引用分组的内容,但是有的时候仅仅想通过分组来进行范围定义,而不想被分组来捕获,通过一个例子就能明白: $str = "http://www.google.com"; $preg= ...

    Python 正则表达式完整示例教程

    文章目录正则表达式元字符基本元字符:预定义字符使用量词贪婪量词字符分组反向引用分组非捕获分组re模块介绍search()和match()函数match对象的方法findall()和finditer()字符串分割和替换编译正则表达式 ...

    历史关系查询语言的完整性-研究论文

    我们显示了时间上未分组的模型不如分组模型强大,但是展示了一种利用分组机制扩展未分组模型以捕获时间分组的附加语义能力的技术。 对于未分组的模型,我们定义了三种不同的语言:时间逻辑,明确引用时间的逻辑和...

    还不会 JavaScript 中的正则表达式 ? 一篇文章带你轻松入门 !

    还不会 JavaScript 中的正则表达式 ? 一篇文章带你轻松入门 ! 文章目录还不会 JavaScript 中的正则表达式 ?... 分组引用③. 反向引用④. 匹配不捕获(?: )-5). 回溯法原理①. 没有回溯的匹配②. 有回溯的匹配

    javascript正则表达式总结

    工具 ...学习正则重要的是实践操作,不妨举个栗子: 匹配号码:707-827-7019 字符组匹配 [0-9][0-9][0-9]-[0-9][0-9][0-9]-[0-9][0-9][0-9][0-9] ...用圆括号()创建分组,用\1来对捕获分组内容进行向后引用 (\d)\d\1 则

    JavaScript中正则表达式判断匹配规则及常用方法

    字符串是编程时涉及到的最多的一种数据结构,对字符串进行操作的需求几乎无处不在。 正则表达式是一种用来匹配字符串的强有力的武器。...\数字n表示指向第n个分组捕获到的字符串文本的一个引用,能够再次被匹配 

    正则表达式30分钟入门教程

    使用小括号指定一个子表达式后,匹配这个子表达式的文本(也就是此分组捕获的内容)可以在表达式或其它程序中作进一步的处理。默认情况下,每个分组会自动拥有一个组号,规则是:从左向右,以分组的左括号为标志,...

    http-supervisor:一个简单的工具,可帮助审核HTTP请求并识别超出设置配额的请求。 它还有助于根据各种参数对请求进行分组,排序和查询

    它还有助于根据各种参数对请求进行分组,排序和查询。 该工具呈现了一个简单的UI,该UI提供了用于捕获请求并以更好的可读格式打印到控制台的控件。 它还提供了一个全局对象供您管理请求。 带有控件的用户界面 ...

    TCP/IP详解

    作者用Lawrence Berkeley实验室的tcpdump程序来捕获不同操作系统和TCP/IP实现之间传输的不同分组。对tcpdump输出的研究可以帮助理解不同协议如何工作。本书适合作为计算机专业学生学习网络的教材和教师参考书。也...

    TCP-IP详解 1-3卷.rar

    作者用Lawrence Berkeley实验室的tcpdump程序来捕获不同操作系统和TCP/IP实现之间传输的不同分组。对tcpdump输出的研究可以帮助理解不同协议如何工作。本书适合作为计算机专业学生学习网络的教材和教师参考书。也...

    TCPIP网络协议讲解

    作者用Lawrence Berkeley实验室的tcpdump程序来捕获不同操作系统和TCP/IP实现之间传输的不同分组。对tcpdump输出的研究可以帮助理解不同协议如何工作。本书适合作为计算机专业学生学习网络的教材和教师参考书。也...

    TCP-IP详解(1~3卷)

    作者用Lawrence Berkeley实验室的tcpdump程序来捕获不同操作系统和TCP/IP实现之间传输的不同分组。对tcpdump输出的研究可以帮助理解不同协议如何工作。本书适合作为计算机专业学生学习网络的教材和教师参考书。也...

    RevNote Highlighter - Web & PDF-crx插件

    在查看网络文章或PDF的同时单击扩展图标,会将文档存储到您的RevNote帐户,并自动捕获所有可用的参考信息。 然后,您可以生成APA,MLA,芝加哥,哈佛,温哥华和其他主要参考样式的引文。 注释保存的Web文章和PDF时,...

    写给大忙人看的JAVA SE 8

    2.11 分组和分片 37 2.12 原始类型流 40 2.13 并行流 42 2.14 函数式接口 44 练习 45 第3章使用lambda编程 48 3.1 延迟执行 50 3.2 lambda表达式的参数 51 3.3 选择一个函数式接口 52 3.4 返回函数 55 3.5 组合 56 ...

    TCP-IP协议详解1,2卷

    作者用Lawrence Berkeley实验室的tcpdump程序来捕获不同操作系统和TCP/IP实现之间传输的不同分组。对tcpdump输出的研究可以帮助理解不同协议如何工作。本书适合作为计算机专业学生学习网络的教材和教师参考书。也...

    一个java正则表达式工具类源代码.zip(内含Regexp.java文件)

    原文如下: 以前写了一个java的正规表达式的java工具类,分享一下,有用到的欢迎下载使用。 如果你有常用的定义好的,且测试通过的正规表达式,欢迎跟贴,也让我享用一下 . 类中用到了 jakarta-oro-2.0.jar 包,请...

    TCP-IP详解.卷一、卷二、卷三

    作者用Lawrence Berkeley实验室的tcpdump程序来捕获不同操作系统和TCP/IP实现之间传输的不同分组。对tcpdump输出的研究可以帮助理解不同协议如何工作。 本书适合作为计算机专业学生学习网络的教材和教师参考书。也...

    TCP-IP详解(三卷齐)

    作者用Lawrence Berkeley实验室的tcpdump程序来捕获不同操作系统和TCP/IP实现之间传输的不同分组。对tcpdump输出的研究可以帮助理解不同协议如何工作,主要讲述TCP/IP协议方面的内容。与其他的TCP/IP书藉的最大不同...

Global site tag (gtag.js) - Google Analytics