【问题标题】:RegEx - Match With Conditional Lookaround?RegEx - 与条件环视匹配?
【发布时间】:2011-08-30 21:10:16
【问题描述】:

我想使用环视来匹配字符串的一部分,但前提是该行中不包含其他单词。

有些熊在树林里生活和进食。

在上面的行中,我想找到“eat in the”(在“live and”和“woods”之间):

/(?<=\blive and\b).*?(?=\bwoods\b)/

但前提是“bears”不在行外,无论是在环视之后、之前还是在环视之间。

其他不应返回匹配的行示例如下:

有些动物在 树林,像熊一样。

有些动物生活和吃熊 树林。

如何将此条件添加到我的正则表达式中?

【问题讨论】:

    标签: regex conditional lookaround


    【解决方案1】:

    这是有问题的,因为大多数版本不支持可变长度的后视,因此您无法检查整行。一个简单的方法是匹配整行而不是使用环视:

    ^(?!.*\bbears\b).*?\blive and\b(.*?)\bwoods\b
    

    这里,之前的整场比赛是第一个捕获组。根据您的使用情况,它可能会使替换此文本不太方便。确保使用 muliline 标志 (/m),而不是设置单行标志 (dot-all 或 /s)。

    工作示例:http://rubular.com/r/TuADb2vB4w

    请注意,如果您可以分两步解决问题,则问题变得非常简单:过滤掉带有\bbears\b的行,并匹配想要的字符串。

    【讨论】:

    • 分两步肯定会更易读。这是个好建议。谢谢。
    • tudor 的答案在大多数情况下都有效,但多行失败。你对此有什么想法吗?
    【解决方案2】:

    在 Perl 中:

    use strict;
    use warnings;
    
    my $a = "Some bears live and eat in the woods.";
    
    #$a = "Some animals live and eat in the woods, like bears.";
    
    $a = "Some animals live and eat bears in the woods.";
    
    $a =~ /(?(?!.*bears.*)(.*\blive and\b(.*)\bwoods\b.*)|(.{0}))/g;
    
    print $2;
    

    条件?(?!.*bears.*)就像

    if the string contains the bears string
       then matches .*\blive and\b(.*)\bwoods\b.*
       else matches .{0}
    

    您不需要在live andwoods 之间进行匹配

    阅读更多关于Regex Conditionals here

    【讨论】:

    • 谢谢!这很好用!似乎 else 是可选的(至少在 AS3 中),如下所示: myString.match(new RegExp("(?(?!.*\\bbears\\b.*)((?
    • 嗯。我可能在这里草率下结论。即使设置了多行标志,此解决方案似乎也不适用于多行。忽略任何带有“熊”的行之后出现的实际匹配行。有什么想法/建议吗?
    • 你希望它如何作用于多行字符串?
    • 评估每一行的条件?我不太确定我是否遵循您的问题。 "live and eat in woods\nbears live and eat in woods\nlive and sleep in woods" 只从第一行返回“eat in”,但由于第二行匹配失败,因为存在单词 bears,所以它也失败了for 并且第三行不返回任何内容,即使第三行应该返回“ sleep in ”。在这种情况下,我希望匹配行返回的数组是(“eat in”,“sleep in”),但它只是(“eat in”,)
    【解决方案3】:

    您的问题和示例似乎不匹配,但您可以执行以下操作:

    (?!.*\bbears\b)(?<=\blive and\b).*?(?=\bwoods\b)
    

    (只是扩展了你的正则表达式)

    【讨论】:

    • 它会漏掉bears 出现在比赛前的情况。我不认为有太多的口味支持这种向后看,这就是我尝试全线方法的原因。 (.Net 在这里是一个例外,类似(?&lt;!^(?=.*\bbears\b).*),但这个问题可能是使用动作脚本)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-07-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多