多次正则表达式捕获组和其他组

Regex capture group multiple times and other groups

我正在尝试制作一个捕获多组数据的正则表达式。

这是一些数据示例:

sampledata=X
B : xyz=1 FAB1_1=03 FAB2_1=01
A : xyz=1 FAB1_1=03 FAB2_1=01

我需要捕获应该出现一次的X,以及FAB1_1=03FAB2_1=01、...所有以FAB开头的字符串。

所以,我可以像这样捕获所有 "FAB" :

/(FAB[0-9]_[0-9]=[0-9]*)/sg

但我无法使用此表达式包含对 X 的捕获:

/sampledata=(?<samplegroup>[0-9A-Z]).*(FAB[0-9]_[0-9]=[0-9]*)/sg

此正则表达式仅 return 一组与 X 和最后匹配的组 "FAB".

你可以使用

(?:sampledata=(\S+)|(?!^)\G)(?:(?!FAB[0-9]_[0-9]=).)*(FAB[0-9]_[0-9])=([0-9]*)‌​

regex demo

正则表达式基于 \G 运算符匹配字符串的开头或 上一次成功匹配的结尾 。我们将其限制为仅在后一种情况下匹配负先行 (?!^).

所以:

  • (?:sampledata=(\S+)|(?!^)\G) - 匹配文字 sampledata=,然后匹配并捕获到第 1 组一个或多个 non-whitespace 符号 - 或 - 匹配上一个成功匹配的结尾
  • (?:(?!FAB[0-9]_[0-9]=).)* - 匹配任何不是 FABn_n= 的文本(这是 tempered greedy token
  • (FAB[0-9]_[0-9]) - 捕获组 2,匹配并捕获 FAB 后跟一个数字,然后是 _,再一个数字
  • = - 文字 =
  • ([0-9]*)‌​ - 捕获组 3,匹配并捕获零个或多个数字

如果你有 1 个 sampledata=,你可以安全地 展开 贪婪代币 (demo ) 作为

(?:sampledata=(\S+)|(?!^)\G)[^F]*(?:F(?!FAB[0-9]_[0-9]=)[^F]*)*?(FAB[0-9]_[0-9])=([0-9]*)
                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

这样,表达效率会更高

如果你有几个sampledata个方块,强化贪婪令牌:

(?:sampledata=(\S+)|(?!^)\G)(?:(?!sampledata=|FAB[0-9]_[0-9]=).)*(FAB[0-9]_[0-9])=([0-9]*)

another demo