我如何选择将未来的字符串与正则表达式匹配?

How do I optionally match future strings with regex?

我有一个正则表达式,如果我明确匹配字符串的不同部分,我可以匹配它。但我需要字符串的某些部分是可选的。字符串的某些部分是递归的并且可以重复:

这是一个字符串示例:[P1]<CX1>=AA1==B-1|R1|[P1]<CX2>-AB1-B2

让我稍微分解一下该字符串的结构。它由以下部分组成:

  1. [Something]
  2. <something>
  3. (#|%|=|-|\+)+[A-Z]*[0-9]* -- 这个模式可以用不同的排列重复(例如 =A1-B2%2##Z 是模式的三个重复)。
  4. \|是分隔符
  5. [A-Z]+[0-9]+
  6. \|另一个分隔符
  7. 在此处重复步骤 1-3

第 4 步及以后的步骤作为一个整体是可选的。因此,如果存在第 4 步,则必须存在所有步骤(包括重复步骤 1-3)。

我有以下问题:

  1. 匹配步骤 3 中可选的重复排列
  2. 匹配从第 4 步开始的所有内容,因为它是可选的

所以所有这些都是有效的,我想要一个正则表达式来捕获步骤 1、2、3(每个排列)和 5 中的组:

[P1]<CX1>=A
[P1]<CX1>%A
[P1]<CX1>-99
[P1]<CX1>=A1-1
[P1]<CX1>=A1-1%C
[P1]<CX1>=A1-1%%C
[P1]<CX1>=A1-1%%C|R1|[P2]<CX1>=A1-23
[P1]<CX1>=A1-1%%C|R1|[P1]<CX2>=A1==B12-C

如果有任何见解和帮助,我将不胜感激。

提前致谢!

最佳,

PS:如果这很重要,我正在使用 ruby 的正则表达式引擎。

如果您想匹配第 1、2、3 组和可选的第 5 组,您可以使用 \G 锚点。

如果只有一个字符串,您可以从 \G:

开始
\G(\[[^\]\[]+\])(<[^<>]*>)([#%=+-][A-Z]*[0-9]*(?:[#%=+-][A-Z]*[0-9]*)*)(?:\|([A-Z]+[0-9]+)\|)?

说明

  • \G 在上一场比赛结束时或开始时(在本例中为开始)断言位置
  • (\[[^\]\[]+\]) 捕获 组 1,匹配从左到右方括号
  • (<[^<>]*>) 捕获 组 2,匹配从左到右尖括号
  • ( 捕获 第 3 组
    • [#%=+-][A-Z]*[0-9]* 匹配任何列出的和可选的字符 A-Z 和数字 0-9
    • (?:[#%=+-][A-Z]*[0-9]*)* 可选择重复之前的模式
  • ) 关闭群组
  • (?:\|([A-Z]+[0-9]+)\|)? 可选择在 2 个管道之间匹配捕获 组 4

Regex demo

如果匹配项不必位于字符串的开头,您可以使用带有交替的锚 |\G(?!\A) 断言它不在字符串的开头。

(?:(\[[^\]\[]+\])(<[^<>]*>)([#%=+-][A-Z]*[0-9]*(?:[#%=+-][A-Z]*[0-9]*)*)|\G(?!\A)\|([A-Z]+[0-9]+)\|)

Regex demo