【问题标题】:Regular expression matching with '?' [duplicate]与 '?' 匹配的正则表达式[复制]
【发布时间】:2012-06-25 21:48:06
【问题描述】:

可能重复:
Regex question mark

我试图弄清楚如何解析出括号内但语句中单引号之间的文本。例如,如果我有以下语句:

(I have a 'cat', 'hat');

我希望结果是

cat
hat

我设法通过尝试维基百科 (http://en.wikipedia.org/wiki/Regular_expression) 中定义的不同元字符来解决这个问题,但我仍然无法理解它为什么起作用。

我试过这个:\'(.*)\'

我对这个正则表达式的理解:我想得到单引号 ' 之间的字符,并且这些字符匹配任何单个字符 . 零次或多次 *

这导致:

cat', 'hat

在玩了一堆正则表达式之后,我终于意外地得到了这个:\'(.*?)\'

这导致:

cat
hat

为什么会这样? (特别是我不明白“?”是如何工作的。)

【问题讨论】:

标签: regex


【解决方案1】:

正则表达式的默认行为是使字符串中的尽可能长匹配。这被称为“贪婪”。

你是对的,? 通常只是意味着匹配前面的项目(例如,字符)一次或多次,但*? 是一种称为“惰性星”的特殊情况,它将正则表达式评估器转换为“懒惰”模式。在这种模式下,评估者首先尝试跳过前面的项目(并在没有它的情况下完成匹配),然后“返回”它。

最终结果正是您所观察到的:它将匹配满足搜索条件的较短字符串,而不是(默认),它只会找到可能最长的匹配项。

here 是测试正则表达式的便捷资源,here 是对各种选项(包括惰性星号)的很好描述。

【讨论】:

  • 需要注意的是,并不是所有的正则表达式方言都支持惰性量词;特别是,根据regular-expressions.info/refflavors.html,POSIX 和 GNU(无论是基本形式还是扩展形式)和 XML 模式正则表达式都不支持它
【解决方案2】:

默认情况下,正则表达式是贪婪的。通过使用问号,您将匹配更改为“惰性”模式。这意味着它匹配尽可能少的字符数。

【讨论】:

    【解决方案3】:

    这行得通,因为,

    () 是对你的结果进行分组(这是你想要得到的回报)。

    . 匹配一切。

    * 让匹配出现 0 次或多次。

    ? 是可选的,因此,ab? 将区分 aab

    最后,(.*?) 将匹配除一次(? 工作)或 0 次或多次(* 工作)之外的所有内容。

    【讨论】:

      【解决方案4】:

      当 * 后跟 ?这使得 * 在惰性模式下匹配。默认情况下,它是贪婪的:尽可能多地吸收匹配的字符。在惰性模式下,它会尽可能早地继续模式的其余部分。

      一开始就搞错了。现在更正了。

      【讨论】:

      • 反之亦然。添加 ?让它变得懒惰。
      • 关闭,但实际上相反。
      猜你喜欢
      • 1970-01-01
      • 2020-07-25
      • 2022-01-22
      • 2016-02-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-08
      相关资源
      最近更新 更多