regex 如何在正向后看和向前看之间选择所有事件?

icnyk63a  于 2023-05-19  发布在  其他
关注(0)|答案(2)|浏览(107)

我想学习如何捕获(?<=...)(?=...)之间出现的所有字符(例如,-)。
假设我有以下文本:

- [abc!word1-word2-word3]
- word1-word2-word3

我的目标是创建一个包含所有-的捕获组,只有当字符串以[abc!开头并以]结尾时才能创建。
我使用gm选项和PCRE2风格尝试了以下操作(例如,参见demo here):

(?<=\[abc!).*(-).*(?=\])

但是,只有最后一次出现的-匹配,如下所示。

有没有办法做到这一点?

xienkqul

xienkqul1#

您可以使用以下命令替换[abc!和下一个(最接近的)]字符之间的每个连字符

(?:\G(?!\A)|\[abc!)[^][-]*\K-(?=[^][]*])

参见regex demo

  • 详情 *:
  • (?:\G(?!\A)|\[abc!)-上一个成功匹配的结束(\G(?!\A),参见this \G reference)或(|[abc!字符串(\[abc!
  • [^][-]*-除[]-之外的零个或多个字符
  • \K-一个match reset operator,它从匹配内存缓冲区中丢弃到目前为止匹配的文本
  • --连字符
  • (?=[^][]*])-一个positive lookahead,确保在当前位置的右边有零个或多个字符,而不是方括号后面紧跟一个]字符。
vwkv1x7d

vwkv1x7d2#

如果您使用的正则表达式引擎不支持\G,只要满足某些条件,以下是实现目标的几种方法。

用例1:您的正则表达式引擎支持变长正向查找(例如C#的引擎)

你可以用

(?<=\[abc!.*)-(?=(?:(?!\[abc!).)*])

Demo
这个正则表达式可以分解如下。

(?<=          # begin positive lookbehind
  \[abc!      # match literals
  .*          # match >= 0 characters other than line terminators
)             # end positive lookbehind
-             # match a literal
(?=           # begin a positive lookahead
  (?:         # begin a non-capture group
    (?!       # begin a negative lookahead
      \[abc!  # match a literal
    )         # end negative lookahead
    .         # match a character other than a line terminator
  )*          # end the non-capture group and execute it zero or more times
  ]           # match a literal
)             # end positive lookahead

情况2:已知字符串中的每个右括号前面都有'[abc!',中间没有右括号

-(?=(?:(?!\[abc!).)*])

Demo
请注意,这个正则表达式与前面的正则表达式相同,只是去掉了正向后看。

相关问题