【问题标题】:Match lines with "1" before 1st-occurence of "xyz"在“xyz”第一次出现之前匹配“1”的行
【发布时间】:2021-09-30 23:55:55
【问题描述】:

我正在寻找一个 PCRE 正则表达式来匹配“xyz”第一次出现之前与“1”的行,所以像...
Anytext1 Anytext2 xyz Anytext1 xyz AnyText1 xyz
Anytext0 Anytext2 xyz AnyText1 xyz Anytext1 xyz AnyText1 xyz AnyText1 xyz

应该只匹配Line1,这可能吗?

编辑:
如果后视支持变量量词,我会使用 ^(.*?xyz)(?<=.*1.*xyz).*
这可以匹配第一个 xyz,然后在某处查找“1”。

字符串长度各不相同,并且 '1' 可以在任何地方,所以我不能使用带有单量词的多个后视。
就像如果我的字符串在 xyz 之前总是 17 个字符,我仍然需要 17 个不同的后视,例如...
^(?:.*?xyz)(?<=.{7}1.{10}xyz).* (匹配 '1' 作为第 8 个字符,就像在 Line1 上一样)
^(?:.*?xyz)(?<=.{8}1.{11}xyz).* (匹配 '1' 作为第 9 个字符)
大声笑,除了匹配所有 17 个位置的 15 个以上,而且我的字符串并不总是 17 个字符长。

解决方案:
幸运的是,@The Fourth Bird 和 @vszholobov 提供了使用负面展望的解决方案ahead。
在 . 之前使用 (.)* 和负前瞻来测试如果 . 匹配,它不是 'x' 后跟 ' yz'。
所以我最终使用的解决方案看起来像...
^((?!xyz).)*1.*xyz.*

仅当 '1' 出现在任何字符串中的第一个 'xyz' 之前时才匹配。
如果您不想任何团体消费,只需插入 ?: 到第一组。再次感谢大家!

【问题讨论】:

  • /^((?!xyz)[^1])*((?<!xyz)1)/gm 试试这个。
  • 不要交叉匹配xyz或1,然后匹配1和匹配xyz ^(?:(?!xyz|1).)*1.*xyz.*regex101.com/r/Qzf5fw/1
  • @K450 谢谢,但运气不好。如果 only 后视有可变量词,我会使用 ^(.*?xyz)(?
  • @第四只鸟感谢!我非常专注于使用后视,我什至没有考虑使用替代方案的前瞻。再次感谢。
  • @The Fourth Bird 和 vszholobov.. 我试图支持你的答案,但它一直说我需要“至少 15 个声望才能投票”!我认为赞成票最终会出现,因为它还说......“但您的反馈已被记录”。不管怎样,我只是想再次感谢你们!

标签: regex regex-lookarounds regex-negation


【解决方案1】:

当1 或xyz 不在右侧时,您可以使用否定前瞻来匹配单个字符。

那么你就可以匹配1和匹配字符串中的xyz了。

^(?:(?!xyz|1).)*1.*xyz.*
  • ^ 字符串开始
  • (?:非捕获组整体匹配部分
    • (?!xyz|1). 负前瞻,断言不是xyz 或1 直接向右
  • )*关闭非捕获组并选择性地重复它
  • 1.*xyz.* 匹配 1 然后 xyz 在字符串中

Regex demo

【讨论】:

    【解决方案2】:

    如果第一次出现1 之前的部分不包含xyz,则需要匹配行。否定look-arounds是可行的。

    Example.

    关于不包含单词here的匹配行的更多信息。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-11-23
      • 1970-01-01
      • 1970-01-01
      • 2022-12-05
      • 1970-01-01
      • 2014-10-28
      • 1970-01-01
      相关资源
      最近更新 更多