`

正则表达式中的懒惰匹配与非捕获组

阅读更多
当正则表达式中包含能接受重复的限定符(指定数量的代码,例如*,{5,12}等)时,通常的行为是(在使整个表达式能得到匹配的前提下)匹配尽可能多的字符。

    考虑这个表达式:a.*b,它将会匹配最长的以a开始,以b结束的字符串。如果用它来搜索aabab的话,它会匹配整个字符串aabab。这被称为贪婪匹配。

    有时,我们更需要懒惰匹配,也就是匹配尽可能少的字符。前面给出的限定符都可以被转化为懒惰匹配模式,只要在它后面加上一个问号?。这样.*?就意味着匹配任意数量的重复,但是在能使整个匹配成功的前提下使用最少的重复。现在看看懒惰版的例子吧:

     a.*?b匹配最短的,以a开始,以b结束的字符串。如果把它应用于aabab的话,它会匹配aab和ab。



举例1:
   表达式 "<td>(.*)</td>" 与字符串 "<td><p>aa</p></td> <td><p>bb</p></td>" 匹配时,匹配的结果是:成功;匹配到的内容是 "<td><p>aa</p></td> <td><p>bb</p></td>" 整个字符串, 表达式中的 "</td>" 将与字符串中最后一个 "</td>" 匹配。
举例2:
   相比之下,表达式 "<td>(.*?)</td>" 匹配举例1中同样的字符串时,将只得到 "<td><p>aa</p></td>", 再次匹配下一个时,可以得到第二个 "<td><p>bb</p></td>"。

懒惰限定符
*? 重复任意次,但尽可能少重复
+? 重复1次或更多次,但尽可能少重复
?? 重复0次或1次,但尽可能少重复
{n,m}? 重复n到m次,但尽可能少重复
{n,}? 重复n次以上,但尽可能少重复

这个例子供测试:
import java.util.regex.*;
public class Test{
  public static void main(String[] args) {
    //String s = "<td><<p>aa</p></td> <td><p>bb</p></td>";//用于其它测试
    String s = "<td>aa555</td><td>bbb</td><td>abc</td>";//用于{1,40},{1,}测试
    //String s = "<td>a</td><td>b</td><td></td>";//用于.??测试
    //String regex="<td>(.*)</td>";

     //String regex="<td>(.*?)</td>";
     // String regex="<td>(.+?)</td>";
     //String regex="<td>(.??)</td>";
     //String regex="<td>(.{1,40}?)</td>";
     String regex="<td>(.{1,}?)</td>";
     Pattern pt=Pattern.compile(regex);
     Matcher mt=pt.matcher(s);
     while(mt.find()){
       System.out.println(mt.group(1).trim());
     }
   }
}

非捕获组(?:Exp):匹配Exp部分正则表达式,但匹配的结果并不保存到捕获组,一般在验证规则时使用,因为保存捕获组都要占用一定的内存资源,而不需要保留匹配结果时,可以使用非捕获组来节省资源

import java.util.regex.*;

public class Test {
  public static void main(String[] args) {
    String str = "<a href=\"11\"> <font color=\"21\">aaa </font> </a>" +
       "<a href=\"12\"> <font color=\"22\">bbb </font> </a>" +
       "<a href=\"13\">ccc </a> " +
       "<a href=\"14\"> <font color=\"23\">ddd </font> </a>" +
       "<a href=\"15\"> <font color=\"25\">eee </font> </a> " +
       "<a href=\"16\">fff </a> ";
    String regex = "<a.*?>(?:\\s*<font[^>]*>)?(.*?)(?:</font>\\s*)?</a>";
    Pattern pattern = Pattern.compile(regex);
    Matcher matcher = pattern.matcher(str);
    while(matcher.find()) {
      System.out.println(matcher.group(1));
    }
  }
}

这个例子的运行结果是:
C:\java>java Test
aaa
bbb
ccc
ddd
eee
fff
分享到:
评论

相关推荐

    正则表达式的匹配规则

    正则表达式是一种强大的文本处理工具,用于在字符串中查找、替换或提取符合特定模式的文本。它在编程、数据分析、文本挖掘等领域有着广泛的应用。本文将深入探讨正则表达式的匹配规则,帮助你理解和掌握这个强大的...

    正则表达式(Word)

    平衡组是指在正则表达式中使用特殊的符号来指定匹配的平衡组。例如,(?&lt;name&gt;pattern) 代表命名的捕获组。 16. 注释 注释是指在正则表达式中使用特殊的符号来指定注释的内容。例如,(?#comment) 代表注释的内容。 ...

    正则表达式.txt,正则表达式.txt

    正则表达式(Regular Expression),简称“regex”或“regexp”,是一种在文本中查找字符串的强大工具。它由一系列字符和特殊符号组成,用于匹配一组符合特定规则的字符串。通过正则表达式,用户可以轻松地实现字符...

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

    - **贪婪与懒惰匹配**:控制正则表达式的匹配行为。 - **原子组和递归模式**:解决复杂的嵌套结构匹配问题。 #### 六、学习资源 - **《Mastering Regular Expressions》**:本书由 Jeffrey E.F. Friedl 编写,是...

    正则表达式详解(20分钟看懂正则)

    正则表达式中有许多元字符,它们具有特殊的含义,而非字面上的字符匹配。例如: - **`\b`**:单词边界,用于匹配单词的开头或结尾。 - **`.`**:任何字符(除换行符外)。 - **`*`**:前面的元素可以出现零次或多次...

    常用正则表达式 正则表达式

    正则表达式(Regular Expression,简称regex)是用于匹配字符串的一种模式,广泛应用于文本处理、数据验证、搜索和替换等场景。它通过一种特殊的语法来描述一个字符串集合,可以非常灵活地表示各种复杂的字符串格式...

    C#正则表达式专题学习(很不错)附正则测试工具

    1. 在提供的压缩包中,"RegexTester.exe"是一个正则表达式测试工具,可以帮助开发者实时测试和调试正则表达式,查看匹配结果、捕获组等内容。 2. 使用测试工具时,输入正则表达式和待匹配的文本,可以直观地看到匹配...

    正则表达式帮助文档(正则表达式)

    正则表达式是一种强大的文本处理...在文档中,你可能会找到更多关于正则表达式的高级特性和实际应用案例,比如正则表达式的递归、条件表达式、平衡组等。记住,精通正则表达式能显著提高你在处理文本时的效率和精确度。

    javaScript 正则表达式详解

    search() 方法用于检索字符串中指定的子字符串,或检索与正则表达式相匹配的子字符串。replace() 方法用于在字符串中用一些字符替换另一些字符,或替换一个与正则表达式匹配的子串。 JavaScript 中的正则表达式提供...

    精通正则表达式(第三版).pdf

    通过使用圆括号 `()` 对正则表达式的一部分进行分组,可以创建捕获组。捕获组允许用户提取匹配的部分,这对于从复杂文本中抽取有用信息非常有用。例如,在匹配电子邮件地址时,可以通过分组来分别获取用户名和域名...

    精通正则表达式(第3版).pdf

    8. 正则表达式的贪婪与非贪婪模式:在正则表达式中,量词(如*、+、?)默认是贪婪的,它会尽可能多地匹配字符;非贪婪模式(或懒惰模式)则匹配尽可能少的字符,通常通过在量词后面加上一个问号(?)来实现。 9. ...

    正则表达式.CHM

    5. 分组:通过`( )`将一部分正则表达式括起来,形成一个分组,可以进行重复、捕获或者非捕获操作。 6. 零宽断言:如`(?=pattern)`是向前断言,确保接下来的字符匹配`pattern`但不包含在匹配结果中;`(?&lt;!pattern)`...

    Python基础入门知识之正则表达式学习 正则表达式30分钟入门教程 共21页.pdf

    正则表达式是编程语言中用于模式匹配的强大工具,尤其在数据处理和文本搜索替换时极为有用。Python作为一门广泛使用的编程语言,内置了强大的正则表达式支持。本教程旨在帮助初学者在30分钟内对Python中的正则表达式...

    正则表达式简明参考.pdf

    正则表达式是一种用于匹配字符串中字符组合的模式。它在各种编程语言、脚本语言以及文本处理工具中广泛使用。以下详细解析了正则表达式中的一些重要知识点: 元字符是正则表达式中具有特殊意义的字符。例如点号(.)...

    python正则表达式的懒惰匹配和贪婪匹配说明

    Python中的正则表达式在处理字符串匹配时有两种主要模式:贪婪匹配和懒惰匹配,这两种模式在处理相同正则表达式时会有不同的行为,对于字符串的解析和提取有着显著的影响。 1. **贪婪匹配(Greedy Matching)** ...

    正则表达式帮助文档 一点正则表达式的文档 随便看看

    1. **元字符**:在正则表达式中,一些特殊字符具有特殊的含义,如`.`代表任意单个字符,`^`表示行首,`$`表示行尾,`\d`代表数字,`\w`代表字母或数字,`\s`代表空白字符。 2. **量词**:用来控制匹配次数。`*`表示...

    正则表达式及常用匹配表达式

    4. **懒惰匹配与贪婪匹配**: - 默认情况下,量词是贪婪的,会尽可能多地匹配。 - 在量词后加上`?`使其变为懒惰的,尽可能少地匹配。 - 示例代码:`foooodfo+?`匹配“fo”而非整个“fooood”。 5. **选择器**: ...

    精通正则表达式_第三版(高清版).

    此外,书中还会介绍一些实用的诀窍,比如如何使用命名捕获组来提高正则表达式的可读性,以及如何构建复杂的正则表达式等。 最后,调校措施主要指的是在开发和调试阶段对正则表达式进行测试和优化的方法,如使用在线...

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

    - **贪婪与懒惰匹配**:默认情况下,正则表达式倾向于尽可能多地匹配(贪婪)。添加`?`使其变为懒惰匹配,即尽可能少地匹配。 #### 7. 平衡组与递归匹配 - **平衡组**:处理嵌套结构,如括号或引号的匹配,确保...

Global site tag (gtag.js) - Google Analytics