【问题标题】:Regex match everything from the last occurrence of either keyword正则表达式匹配任何一个关键字最后一次出现的所有内容
【发布时间】:2011-03-26 12:24:29
【问题描述】:

我正在尝试匹配从关键字(foo 或 bar)的最后一次出现到字符串末尾的所有内容。

例子(一):

// I want to match ' foo do you?';
$source = 'This is foo and this is bar i like foo do you?';
$pattern = '/pattern/';
preg_match($pattern, $source, $matches);

我尝试了以下方法:

$pattern = '/( (foo|bar) .*)$/';

认为它会匹配最后一次出现的 foo 和所有以下文本,但它却匹配第一次出现。

print_r($matches);

/*
Array
(
    [0] =>  foo and this is bar i like foo do you?
    [1] =>  foo and this is bar i like foo do you?
    [2] => foo
)
*/

注意我关心如何做到这一点的理论和推理,所以请添加一些解释或相关解释的链接。

【问题讨论】:

  • 我在示例中使用了 PHP,但语言无关紧要。我唯一的标准是该模式符合 PCRE。

标签: regex preg-match


【解决方案1】:
.+((foo|bar).+)$

.+ 匹配前面的许多字符。

((foo|bar) 匹配并捕获您的关键字。

.+) 匹配并捕获许多字符。

$ 匹配字符串/行的结尾。

使用您的示例:

This is foo and this is bar i like foo do you?
                                   ^---------^

【讨论】:

  • 澄清一下,删除?: 会将我的关键字(foo|bar) 添加到我的匹配项中,对吗?
  • 另外,有没有办法在不匹配字符串开头的情况下调整此解决方案?即^.+。本质上是告诉正则表达式模式匹配器从字符串末尾评估我的模式?
  • 为了清楚起见,我删除了 ?: 因为它不是必需的。我也更新了示例并删除了“^”,因为它可能不需要。这将从最后的“foo”或“bar”开始匹配到字符串/行的末尾。
  • 这就是我一直在寻找的东西。请注意,您的评论并未准确反映您的编辑。
  • 很高兴它有帮助。它怎么不反映我的评论?我错过了什么?
【解决方案2】:

在你的模式之前使用一个贪婪的匹配来尽可能多地消耗干草堆:

>>> import re
>>> source = 'This is foo and this is bar i like foo do you?'
>>> pattern = '.*((?:foo|bar).*)'
>>> re.search(pattern, source).groups()[0]
'foo do you?'

一种更好的方法是使用负前瞻:

>>> # Negative look-ahead for the pattern: (?!.*(?:foo|bar))
>>> pattern = '((?:foo|bar)(?!.*(?:foo|bar)).*)'
>>> re.search(pattern, source).groups()[0]
'foo do you?'

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-04-18
    • 1970-01-01
    • 2022-11-23
    • 1970-01-01
    • 1970-01-01
    • 2014-10-19
    • 2022-10-13
    • 2018-12-14
    相关资源
    最近更新 更多