`

分组 捕获 引用

    博客分类:
  • 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)");
一个正则表达式就可解决。

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

 

分享到:
评论

相关推荐

    java-正则表达式-分组引用介绍

    ### Java中的正则表达式:分组引用介绍 #### 概述 正则表达式是计算机科学中一种非常强大的文本处理工具,在Java等编程语言中广泛应用于字符串匹配、搜索替换等场景。当需要对正则表达式的部分结果进行进一步处理...

    PHP实现正则表达式分组捕获操作示例

    分组捕获通过将正则表达式的一部分放入括号中实现,括号中的内容即为一个捕获组,可以在匹配过程中被捕获并用于之后的引用。 在PHP中进行正则表达式分组捕获操作,主要是通过preg_match()函数和preg_replace()函数...

    正则表达式之捕获组/非捕获组介绍

    非捕获组:虽然使用小括号可以创建捕获组,但有时候我们只是想要应用小括号的优先级或分组功能,而不需要捕获匹配的文本。这时可以使用(?:pattern)的语法来创建一个非捕获组。 举个例子,如果我们只想匹配一个由...

    浅谈JavaScript正则表达式-非捕获性分组

    非捕获性分组可以让你指定一个子表达式进行分组,但不存储这个分组的匹配结果,也就是说这个分组匹配到的内容不能在正则表达式外部被引用。非捕获性分组在需要应用量词(如*、+、?等)或者使用前瞻(如(?=...))和后...

    浅谈正则表达式中的分组和引用实现方法

    非捕获分组通常用在只需要应用量词而不需要引用该分组内容的场景。 在学习正则表达式的过程中,参考一些权威书籍会非常有帮助,比如《正则表达式经典实例》一书中的第10章往往对初学者理解分组和引用有着至关重要的...

    正则基础之——捕获组(capture group).rar

    5. **反向引用**:在某些正则表达式引擎中,可以使用反向引用(`\g&lt;number&gt;`)来引用前面捕获组的匹配结果,例如`\g&lt;1&gt;`代表第一个捕获组的内容,这对于复杂模式的匹配非常有用。 6. **命名捕获组**:在支持高级...

    JS正则表达式之非捕获分组用法实例分析

    3. 非捕获分组的一个常见的用途是进行分组,但是不需要将该组的内容保存下来供后续引用。 为了方便大家学习JavaScript正则表达式,可以使用在线正则表达式测试工具和在线正则表达式生成工具。这些工具可以帮助你...

    SQL Server 2005 数据转换服务中的模糊查找和模糊分组

    * 高度的辨别力:模糊查找和模糊分组可以捕获更详细的数据结构,结果获得的辨别力要精细得多。 * 无语言依赖:模糊查找和模糊分组不像 soundex 那样有依赖于语言的组件。 * 高度的灵活性:模糊查找和模糊分组可以...

    正则表达式、分组、子匹配(子模式)、非捕获子匹配(子模式)

    例如,如果我们想要查找一对互不相邻的标签内的内容,可以通过正则表达式实现,但需要保留分组中的捕获内容,因为反向引用要求子匹配能够被存储和引用。例如,正则表达式/&lt;(\S+)[^&gt;]*&gt;[^&lt;]*&lt;\/\1&gt;/能够匹配HTML标签...

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

    例如,在使用String.prototype.replace方法时,可以通过分组捕获的字符串对文本进行格式化或替换。如果希望将日期格式从“12.21/2012”转换为“2012-12-21”,可以使用正则表达式进行分组和捕获,然后在replace方法...

    Django之无名分组和有名分组的实现

    - **参数名称**:无名分组捕获的参数名称是任意的,而有名分组捕获的参数名称是固定的。 - **使用灵活性**:无名分组允许视图函数定义更灵活的参数列表,而有名分组则要求参数名称与URL配置中定义的名称完全一致。 -...

    PCAP下一代(pcapng)捕获文件格式

    "PCAP 下一代(pcapng)捕获文件格式" PCAPNG(PCAP Next Generation)是一种捕获文件格式,旨在取代传统的libpcap格式。该格式的设计目标是提供一个可扩展、灵活、便携的捕获文件...包括规范性参考、资料性引用等。

    PHP正则表达式之捕获组与非捕获组

    捕获组与非捕获组是正则表达式中的重要概念,它们允许我们在正则表达式中对匹配的部分进行分组,并且可以选择是否对这些分组进行存储以便后续引用。 首先我们来了解一下什么是捕获组。捕获组是通过将正则表达式的一...

    java正则表达式学习笔记之命名捕获

    java正则表达式中的命名捕获是一个非常实用的特性,它允许开发者在正则表达式中给每一个捕获组设置一个唯一的名称,这样在后续的处理过程中,可以通过名称来引用对应的捕获组。这个特性在Java 7中被引入,其语法和...

    JavaScript 正则命名分组【推荐】

    当正则表达式中捕获分组的数量、顺序或嵌套发生变化时,使用命名分组不需要对引用这些分组的代码进行调整。 #### 3. 更加灵活的反向引用 命名分组使得反向引用更加灵活。例如,可以使用`(?&lt;name&gt;pattern)\k&lt;name&gt;`...

    深入理解JS正则表达式---分组

    正则表达式中的分组是一种用于将正则表达式的一部分括起来,以便可以单独引用该部分匹配的内容的构造。分组在JavaScript正则表达式中非常重要,因为它们不仅可以帮助我们实现复杂的匹配模式,而且还能提取出更细粒度...

    Python正则捕获操作示例

    通过本篇文章,我们将深入探讨Python中的正则捕获操作,包括分组、捕获以及替换等功能,并通过具体的实例进行详细说明。 #### 一、正则捕获的基本概念 在正则表达式中,“捕获”指的是将匹配到的子串存储起来以便...

    Java正则表达式的替换和分组功能

    分组的引用可以通过反斜杠加数字来实现,其中数字对应的是分组的编号。例如,表达式 `(.)\\1` 表示引用第一个分组中匹配的字符。 分组不仅可以用于引用,还可以用于提取和重构字符串。在一些复杂的匹配场景中,使用...

    SQL Server Integration Services 2005中的模糊查找和模糊分组.pdf

    模糊分组转换在处理数据中的常见错误方面具有复原能力,它通过分组来标识记录,有助于将客户引用表中的所有记录归类到一起。 模糊查找和模糊分组在使用上有以下几个优势: 1. 它们使用了自定义的距离函数来计算编辑...

    javascript正则表达式中分组详解

    分组的主要作用是将正则表达式中的一部分模式括起来,以便之后引用这部分匹配的子串。分组分为捕获性分组和非捕获性分组,它们在正则表达式的功能和使用上有所区别。 捕获性分组是默认的分组方式,每当你使用一对圆...

Global site tag (gtag.js) - Google Analytics