【问题标题】:Perl Simple RegexpPerl 简单正则表达式
【发布时间】:2013-11-12 01:43:22
【问题描述】:

我有一个有效的字符串somestr xyztip,其中xyz 是可选的。但是如果xyz 确实存在,它需要在tip 旁边(没有空格)。 所以有效的字符串是:somestr tip 或 somestr xyztip。

无效的字符串是:somestr xyz tip(xyz 和 tip 之间的空格)

我尝试了很多组合,但我无法让正则表达式在“xyz”和“tip”之间的空格处犹豫。下面的一个是我认为应该起作用的:

/^.+?\s(xyz)?tip$/

问题是 '(xyz)?' 之前的语法- 那是 '.+?\s' 。这是说任何字符 1 次或多次,而不是贪婪地后跟一个空格。

我在这里错过了什么?

【问题讨论】:

  • 你想捕捉什么?
  • 所以xyz不能出现在字符串中的任何位置,除非它直接出现在tip之前?那么字符串'tuvwxyz tip' 和'tuvwxyz xyztip' 会无效吗?
  • somestr 不相关吗? IE。您正在寻找字符串xyztip,而不是xyz tip?
  • 正确,somestr 无关紧要,因为在可选的 'xyz' 之前有内容。
  • 所以,@CraigP...这意味着“somexyzstr tip”和“somexyzstr xyztip”是有效的,但“somexyzstr xyz tip”不是......对吗?

标签: regex perl


【解决方案1】:

假设xyz 不能在字符串中的任何位置,除了紧接在tip 之前,以下应该可以工作:

/^((?!xyz).)+\s(xyz)?tip$/

这会将.+? 更改为((?!xyz).)+。通过在重复组中放置负前瞻,我们可以匹配任意数量的字符,但如果遇到xyz,则停止,因此((?!xyz).)+ 将匹配来自“fooxyz”的“foo”。这使我们能够确保 xyz 永远不会与正则表达式的第一部分匹配,因此如果它存在,它必须在正则表达式的 (xyz)?tip 部分中。

【讨论】:

    【解决方案2】:

    你需要的是一个“零宽度正向预测断言”......所以,你的正则表达式看起来像:

    \S+\s(?:xyz)?(?=tip)
    

    来自perldoc perlre:

    "(?=pattern)"
        A zero-width positive look-ahead assertion.  For example, "/\w+(?=\t)/"
        matches a word followed by a tab, without including the tab in $&.
    

    【讨论】:

      【解决方案3】:

      你可以用这个:

      ^(?>[^ ]++| (?!xyz))+ (?:xyz)?tip$
      

      【讨论】:

      • 感谢您的所有回复......使用前瞻断言,它似乎无法识别空白类型代码(即 - \s)。
      • 对不起,这个更好:^\S+ (?:xyz)?tip$
      • @CraigP:当然可以,但是在这种模式下,somestr 不能包含空格。
      • @CraigP: 模式^.+?\S (?:xyz)?tip$ 也可以工作,但会更慢。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-04-11
      • 1970-01-01
      • 2021-04-30
      • 2011-12-18
      • 1970-01-01
      • 2012-07-22
      • 1970-01-01
      相关资源
      最近更新 更多