【问题标题】:pcre regexp - weird Lookbehind assertion is not fixed widthpcre regexp - 奇怪的 Lookbehind 断言不是固定宽度
【发布时间】:2015-08-13 22:50:30
【问题描述】:

我对正则表达式有些陌生,我正在尝试理解这个正则表达式:

(?<!mix\s|mixe[rds]\s|mixing\s)with(?:out)?

在我看来是搜索withwithout,如果它后面没有以下单词:

  • 混合
  • 混合器/混合/混合
  • 混合

所以我试图将其重写为:

(?<!mix(?:e[rnds]|ing)?\s)with(?:out)?

但我收到以下错误:

  • Lo​​okbehind 断言不是固定宽度

我了解lookbehind 的工作原理(它返回固定宽度,然后尝试匹配),但是lookbehind 中的两个正则表达式不是同一个正则表达式吗?

(我在这里找到了一些信息,但我仍然不清楚为什么在这种情况下它不起作用) What's the technical reason for "lookbehind assertion MUST be fixed length" in regex?

【问题讨论】:

    标签: regex pcre


    【解决方案1】:

    在这种情况下它不起作用,因为子模式包含一个量词?。当找到这个量词时,正则表达式引擎决定您的子模式不再有固定长度(这是真的)。​​

    即使两个子模式是等价的(但正则表达式引擎忽略了这一点),存在量词的事实也会导致模式分析失败。

    另一方面,pcre 接受几个固定长度的子模式,由管道分隔。

    避免 pcre 出现此问题的经典解决方法是使用 \K 功能丢弃以前从匹配结果中找到的字符:

    (?<!mix)(?:e[rnds]|ing)?\s\Kwith(?:out)?
    

    【讨论】:

    • 似乎引擎需要补丁。如果我有一个*+,我会理解,这使得无法预先确定长度,但是 ?表示存在与否,因此可以分解子模式以找到宽度并使用它。我对这些信息真的很感兴趣,因为我想在我的下一个项目中,我想创建一个正则表达式生成器。你给出你想要包含和排除的单词,它会给出一个优化的正则表达式
    • @Fabrizio:允许? 或其他量词完全相同,因为在这种情况下,您可以在子模式中放置任意数量的?(并最终嵌套)。 “自动生成优化的正则表达式”:你在做梦吗?
    • @Fabrizio:也许使用回溯控制动词可能是一个不错的选择,特别是组合 (*SKIP)(*FAIL) 或者如果您使用捕获组来选择您想要的分支和丢弃的分支。 (这两种方法的主要思想是消耗你想要避免的字符)
    • 从来没有听说过这样的事情。在这种情况下你会如何应用它?
    • @Fabrizio:看看这个帖子:stackoverflow.com/questions/24534782/…
    猜你喜欢
    • 1970-01-01
    • 2019-03-14
    • 1970-01-01
    • 1970-01-01
    • 2016-04-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-04
    相关资源
    最近更新 更多