正则表达式 - 匹配直到可能出现或不出现的组

Regex - match until group that may or may not occur

我有以下文字:

:3:Start!@#$%^&*():31:Start!@#$%^&*():31:End!@#$%^&*():3:End

并使用以下正则表达式:

(:3:Start)(.*)(:31:Start.*:31:End)?(.*)(:3:End)

为什么存在group3却找不到。即使我将 group2 设置为不贪心:

(:3:Start)(.*?)(:31:Start.*:31:End)?(.*)(:3:End)

如果它出现在文本中间,我如何捕获带有可选子组的组

如果将 (.*?)(:31:Start.*:31:End) 组包含在可选的非捕获组中(用贪婪的 ? 量词量化)并使可选的组 强制性:

(:3:Start)(?:(.*?)(:31:Start.*:31:End))?(.*)(:3:End)
          |____________________________| 

regex demo。它会像这样工作:

  • (:3:Start) - 将 :3:Start` 字符串
  • 捕获到第 1 组
  • (?:(.*?)(:31:Start.*:31:End))? - 将尝试匹配一次模式序列:
    • (.*?) - 第 2 组:除换行字符外的任何 0 个或多个字符尽可能少
    • (:31:Start.*:31:End) - 第 3 组::31:Start.*:31:End 字符串
  • (.*) - 第 4 组:除换行字符外的任何 0 个或更多字符尽可能多
  • (:3:End) - 捕获到第 5 组 :3:End 字符串

为什么你的模式不起作用

参见your pattern demo!@#$%^&*():31:Start!@#$%^&*():31:End!@#$%^&*() 子字符串被捕获到第 4 组,与 (.*) 模式匹配。发生这种情况是因为 (.*?)(:31:Start.*:31:End)? 首先跳过 .*? 模式(它是惰性的,非贪婪的,引擎在第一次看到这样的模式时甚至不会尝试匹配它,它继续匹配强制模式,并且仅在后续模式不匹配时返回),并且 (:31:Start.*:31:End)? 匹配 :3:Start 子字符串之后的空字符串。其余找到匹配项,因此,没有可选文本与您预期的组匹配。