【问题标题】:Regex matching the smallest number of characters匹配最少字符数的正则表达式
【发布时间】:2017-04-19 06:37:27
【问题描述】:

什么一般的(即不包括任何特定于整个模式的文字)PCRE 子表达式放在两个子表达式之间,每个子表达式都由文字字符组成,会导致模式匹配最少数量的字符?

请注意,此问题不满足:

  • this related question 的任何现有答案。

  • 我在本网站上找到的其他相关问题的任何现有答案,包括可能已经有你答案的问题提出的所有问题。

  • .*?(懒惰)。这(如here 所述)不一定匹配最少的字符数。

  • [^x]* 其中 x 是从模式中其他地方复制的文字字符。要求是通用的表达式,即不包括任何特定于整个模式的文字。为避免引出此类错误答案,此问题特意不提供失败模式的示例。

【问题讨论】:

  • 嗯,一个很好的例子是您的链接之一:abcabk,其中a.+?k 匹配整个字符串,而不仅仅是最后 3 个字符。 (解决方案确实是将双字符复制到 Not-set 中——这是您要避免的。)
  • 你到底想做什么?
  • 这个网站是针对您所面临的实际问题的具体问题。您的问题过于模糊和范围广泛。投票结束,直到它变得更加具体,带有实际的问题陈述和具体问题。
  • 我没有阻止任何事情。搁置一个问题需要 5 票。我有礼貌地向你解释了我为什么要这样做。这是一个更好的主意:为什么不编辑您的问题以使其更具体,以便我可以删除我的近距离投票?
  • 这个问题没什么含糊的。他想知道哪个whatever 会给他在leftwhateverright 的任何地方的最短匹配,而不是left.*?right 给出的最左边的最短匹配,并附加要求解决方案不应该要求whateverleftright 发生变化,因此正则表达式可以用作模板。

标签: pcre


【解决方案1】:

此正则表达式查找以left 开头并以right 结尾的最短匹配,并允许其间的任何文本:

(left)(?:(?!(?1)).)*?(?:right)

此正则表达式适用于 PCRE 和任何其他支持 subroutine calls 的风格。 leftright 位不必是文字文本。只要它们不匹配相同的文本,它们就可以是任何正则表达式。您需要考虑的唯一其他问题是,如果 leftright 包含捕获组,那么与作为独立正则表达式的 leftright 相比,这些组的数量将发生变化。

回溯正则表达式引擎总是返回最左边的匹配项。在 leftright 不同的情况下,我们可以强制它返回最短匹配,方法是确保匹配不包含多次left

leftright 相同时,没有纯正则表达式解决方案。然后你可以做的是沿着left的所有匹配分割字符串,然后在结果数组中找到最短的字符串。

【讨论】:

  • 这很好,但如果左右子模式可以匹配相同的东西,这可能不起作用。
  • @jan 啊,酷。使用子例程引用左侧文字的负前瞻,从而将左侧从正文中排除。然后身体通配符懒惰地从身体中排除正确的文字。虽然它不太符合要求(“放置在两个子表达式之间,每个子表达式都由 /literal/ 字符组成”),但它确实很有用,并且是迄今为止最好的答案! :-) 谢谢。
  • @Walf 我一直找不到这样的失败案例。你能举出一个吗?
  • @Jan,当捕获组在“左”之前存在时,这将失败。修复(对于 PCRE >=7.0 和 PCRE2)是 (left)(?:(?!(?-1)).)*?(?:right)
  • (marker)(?:(?!(?1)).)*?marker 反对 markerXXXmarkerXmarker
猜你喜欢
  • 1970-01-01
  • 2014-01-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-05
  • 2013-12-25
相关资源
最近更新 更多