【问题标题】:Regex: Match only if string A is found and string B is not正则表达式:仅当找到字符串 A 且未找到字符串 B 时才匹配
【发布时间】:2011-09-17 03:39:42
【问题描述】:

我需要这是一个单一的正则表达式,因为它进入了 Google 搜索设备的“请勿抓取”列表。 (我相信 Google 正则表达式类似于 GNU 正则表达式。)所以我也没有选择使用代码(任何语言)来代替。

以前有人问过这个问题,但答案通常是代码而不是正则表达式。

我想要做的是匹配一个字符串,如果它包含子字符串 aaa 仅当它不包含子字符串 bbb 时。

作为更具体的示例:如果字符串包含“/RFA/”,但仅当它不包含“Google=yes”时,我想匹配。

所以:“blahblah/RFA/index.cfm?Review=1&blahblah”应该匹配。

但是:“blahblah/RFA/index.cfm?Review=1&Google=yes&blahblah”应该会失败。

顺便说一句,如果它简化了任何事情,那么当它出现时,bbb 子字符串将始终位于 aaa 子字符串之后。

【问题讨论】:

  • 您只需要负前瞻和后视,在字符串的任一侧搜索“bbb”。
  • @Neil 我不确定基本的 GNU 正则表达式是否支持前瞻和后瞻。
  • 那就不可能了。 Lookahead 和lookbehinds 使得在其周围环境中捕获值成为可能。另一种方法是捕获整个表达式,除非允许捕获组。

标签: regex


【解决方案1】:

做到这一点的唯一合理方法是/foo/ && !/bar/。但是,还有其他不太卫生的方法。

/^ (?= (?!NOPAT) . )* $ ) YESPAT /xs

【讨论】:

  • /foo/ && !/bar/ 准确表达了我想要实现的目标,但是,您的解决方案在 Google 模式测试器中不匹配(GNU 正则表达式不支持前瞻?)
【解决方案2】:

注意:不适用于 GNU 正则表达式,仅用于修复 Jonathan 的帖子

@乔纳森。那是行不通的,因为 .* 会贪婪地捕获到行尾,然后才尝试寻找Google=yes。所以它永远不会匹配Google=yes

这个修改会更好:

/^.*\/RFA\/(?!.*Google=yes)/

见:http://codepad.org/hohjsdeI

【讨论】:

    【解决方案3】:

    试试这个:

    /^.*\/RFA\/(?!.*Google=yes)/
    

    这是使用负前瞻,您的正则表达式引擎可能支持也可能不支持。

    ================================================ ============================

    编辑:

    我认为我们已经看到了足够多的证据表明您的正则表达式引擎不具有前瞻性。所以我能想到的唯一其他方法是做 2 次测试:

    /\/RFA\//
    

    /Google=是/

    并且可接受的条件是 TEST1 && !TEST2,这必须通过您的代码比较测试结果来完成。不那么干净,但它可以完成工作。

    【讨论】:

    • 那行不通。 not 部分可能在一开始就隐藏了。
    • 在我的情况下,not 部分总是在所需部分之后,但是,它似乎仍然不起作用。
    • @Mike:这行不通因为他忘记量化 not 部分。请参阅我的回答。
    • @tchrist:啊,是的,根据 Jacob 的建议更正,我已将 .* 移至 () 内。
    • @Mike:正如我在答案中提到的那样,您的正则表达式引擎可能不支持前瞻。
    猜你喜欢
    • 2015-02-02
    • 2021-01-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多