`

Java:正则匹配的不同情况(贪婪,勉强): greedy, reluctant, possesive

    博客分类:
  • java
阅读更多

import java.util.regex.Matcher;

import java.util.regex.Pattern;

 

public class Test {

public static void main(String[] args) {

String str = "<biao><>c<b>";

Pattern pattern;

Matcher matcher;

 

// 贪婪: 最长匹配 .* : 输出: <biao><>c<b>

pattern = Pattern.compile("<.*>");

matcher = pattern.matcher(str);

while (matcher.find()) {

System.out.println(matcher.group());

}

 

// 不知是否非贪婪 .*? : 输出: <biao>, <>, <b>

pattern = Pattern.compile("<.*?>");

matcher = pattern.matcher(str);

while (matcher.find()) {

System.out.println(matcher.group());

}

 

// 使用组, 输出<>里的内容, 输出: 'biao', ' ', 'b'

// 0组代表整个表达式, 子组从1开始

pattern = Pattern.compile("<(.*?)>");

matcher = pattern.matcher(str);

while (matcher.find()) {

System.out.println(matcher.group(1));

}

}

}

  在贪婪、勉强和侵占三个量词间有着细微的不同。

 

  贪婪(*, ?, +):读入整个串,从后往前匹配

  勉强(*?, ??, +?):从前往后匹配

  侵占(*+, ?+, ++):读入整个串,从前往后匹配,匹配的是整个串
  贪婪量词之所以称之为“贪婪的”,这是由于它们强迫匹配器读入(或者称之为吃掉)整个输入的字符串,来优先尝试第一次匹配,如果第一次尝试匹配(对于整个输入的字符串)失败,匹配器会通过回退整个字符串的一个字符再一次进行尝试,不断地进行处理直到找到一个匹配,或者左边没有更多的字符来用于回退了。赖于在表达式中使用的量词,最终它将尝试地靠着 1 或 0 个字符的匹配。
  但是,勉强量词采用相反的途径:从输入字符串的开始处开始,因此每次勉强地吞噬一个字符来寻找匹配,最终它们会尝试整个输入的字符串。
  最后,侵占量词始终是吞掉整个输入的字符串,尝试着一次(仅有一次)匹配。不像贪婪量词那样,侵占量词绝不会回退,即使这样做是允许全部的匹配成功。
  为了说明一下,看看输入的字符串是 xfooxxxxxxfoo 时。

Enter your regex: .*foo  // 贪婪量词
Enter input string to search: xfooxxxxxxfoo
I found the text "xfooxxxxxxfoo" starting at index 0 and ending at index 13.

Enter your regex: .*?foo  // 勉强量词
Enter input string to search: xfooxxxxxxfoo
I found the text "xfoo" starting at index 0 and ending at index 4.
I found the text "xxxxxxfoo" starting at index 4 and ending at index 13.

Enter your regex: .*+foo // 侵占量词
Enter input string to search: xfooxxxxxxfoo
No match found.

  第一个例子使用贪婪量词.*,寻找紧跟着字母“f”“o”“o”的“任何东西”零次或者多次。由于量词是贪婪的,表达式的.*部分第一次“吃掉”整个输入的字符串。在这一点,全部表达式不能成功地进行匹配,这是由于最后三个字母(“f”“o”“o”)已经被消耗掉了。那么匹配器会慢慢地每次回退一个字母,直到返还的“foo”在最右边出现,这时匹配成功并且搜索终止。
  然而,第二个例子采用勉强量词,因此通过首次消耗“什么也没有”作为开始。由于“foo”并没有出现在字符串的开始,它被强迫吞掉第一个字母(“x”),在 0 和 4 处触发了第一个匹配。测试用具会继续处理,直到输入的字符串耗尽为止。在 4 和 13 找到了另外一个匹配。
  第三个例子的量词是侵占,所以在寻找匹配时失败了。在这种情况下,整个输入的字符串被.*+消耗了,什么都没有剩下来满足表达式末尾的“foo”。
  你可以在想抓取所有的东西,且决不回退的情况下使用侵占量词,在这种匹配不是立即被发现的情况下,它将会优于等价的贪婪量词。

贪婪、勉强和侵占量词间的不同
分享到:
评论

相关推荐

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

    Java正则表达式是Java语言中用于处理字符串的强大工具,它允许程序员进行复杂的字符串匹配、查找和替换操作。正则表达式(Regular Expression)是一种模式匹配语言,通过特定的语法来描述字符串的模式,用于在文本中...

    java正则表达式.pdf

    ### Java正则表达式详解 #### 一、引言 正则表达式是计算机科学中的一个强大工具,用于处理文本数据。随着Java的发展,自J2SE 1.4版本开始,Java正式引入了对正则表达式的支持,并提供了一系列功能强大的API。本文...

    JS正则表达式学习之贪婪和非贪婪模式实例总结

    在正则表达式中,有一个重要的概念是贪婪与非贪婪模式(也称为勉强模式),它们决定了正则表达式匹配字符串的方式。本文将详细介绍JavaScript中正则表达式的贪婪模式和非贪婪模式,包括它们的具体功能、使用方法和...

    正则表达式的构造摘要

    正则表达式是一种强大的文本处理工具,用于模式匹配和搜索替换等操作,广泛应用于各种编程语言,如Java中。本文将深入解析正则表达式的构造摘要,帮助读者理解和掌握正则表达式的各种元素和语法。 ### 一、转义序列...

    正则表达式

    1. Greedy(贪婪)数量词:默认行为,尽可能多地匹配字符。 2. Reluctant(勉强)数量词:使用`?`修饰,尽可能少地匹配字符。 3. Possessive(所有的)数量词:使用`+`修饰,一旦匹配成功,不再回溯。 举例应用: -...

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

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

    rgf:正则化贪婪森林(RGF)库的主存储库。 它包括本文的原始实现和用C ++编写的多线程代码,以及各种特定于语言的包装器

    另一种是采用完全校正的正则化贪婪算法。 该存储库包含RGF算法的以下实现: :本文的原始实现; :具有一些简化的多核实现; :Python的RGF和FastRGF实现的包装; :Rgf_python的包装R。 您可能希望从收集的...

    正则式与样式对比概论RegularExpression.pdf

    - **非贪婪量词(Non-greedy Quantifier)**:使匹配尽可能短,与默认的贪婪模式相反。 - **POSIX标准**:Portable Operating System Interface的缩写,为正则表达式提供了一套标准化的语法和行为。 - **交替...

    通过Java正则表达式去掉SQL代码中回车换行和多余空格

    首先,我们来了解正则表达式中的贪婪模式(Greedy)、非贪婪模式(Reluctant)和占有模式(Possessive)。这三种模式主要通过在量词后添加不同的符号来区分,它们对正则表达式的匹配行为有着重要的影响: 1. 贪婪...

    详解正则表达式的贪婪模式与非贪婪模式

    非贪婪模式下,正则表达式会尽可能少地匹配字符,即它会在满足条件的情况下,尽快停止匹配并给出结果。继续上面的例子,如果正则表达式 "ab*?c" 被用来匹配字符串 "abcaxc",在非贪婪模式下,它只会匹配到 "abc"。 ...

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

    * Summary of regular-expression constructs 正则表达式结构简介: * Construct Matches * Characters 字符: * x The character x x 字符 x * \\ The ...

    python中如何使用正则表达式的非贪婪模式示例

    在正则表达式中,贪婪与非贪婪模式是两种不同的匹配策略,它们主要影响由量词(如*、+、?或{m,n})修饰的子表达式的匹配行为。 **贪婪模式**: 在默认情况下,正则表达式采用贪婪模式,它会尽可能多地匹配字符。...

    正则表达式检查小工具

    `Matcher`提供了诸如`matches`、`find`、`group`等方法来检测匹配情况和提取匹配内容。 对于“正则表达式检查小工具”,它可能提供了以下功能: - 输入正则表达式和测试字符串,判断正则表达式是否能正确匹配。 - ...

    正则表达式的学习源码

    例如,创建一个正则表达式,包含捕获组和非捕获组,使用贪婪或非贪婪匹配,以及应用或关系和零宽度断言进行文本匹配和提取。通过实例化`Pattern`对象,调用`matcher(String input)`方法,然后使用`matches()`, `find...

    正则表达式(regex) 贪婪模式、懒惰模式使用方法

    贪婪模式(Greedy Mode)是正则表达式默认的匹配模式。当使用贪婪匹配时,正则表达式引擎尽可能多地匹配符合模式的字符。在贪婪模式下,正则表达式会匹配尽可能长的字符串。例如,如果模式是".*"(点号匹配任意字符...

    正则表达式入门教程(pdf版

    随着学习的深入,会接触到更复杂的概念,如字符类(class)、分枝条件(branch)、分组(group)、后向引用(backreference)、零宽断言(lookaround)以及贪婪与懒惰匹配(greedy and lazy matching)等。...

Global site tag (gtag.js) - Google Analytics