首页 > 解决方案 > 替换正则表达式循环中的组

问题描述

我有这两条线:

What is P(output1|cause1=2, cause2=2)
What is P(output2|cause3=2)

我想将其更改为:

method_to_use(model, {"cause1": 2, "cause2": 2}, "output1")
method_to_use(model, {"cause3": 2}, "output2")

这是我的正则表达式:

.*P[(]([a-z1-9]+)[|](([a-z1-9]+)=([1-9]),?)+[)]

我尝试像这样替换它:

method_to_use(model, {"$3": $4}, "$1")

但我只得到该组的最后一个:

method_to_use(model, {"cause2": 2}, "output1")

是否可以做某种“循环”并在途中改变所有配合?

标签: regexsublimetext3regex-group

解决方案


您可以将字符串与以下正则表达式匹配。

^.*P\(([^|]+)\|([^=]+)=(\d+)(?:, +([^=]+)=(\d+))?\)$

如果捕获组 4 非空,则将(整个字符串)匹配替换为

method_to_use(model, {"$2": $3, "$4": $5}, "$1")

这会导致字符串

What is P(output1|cause1=2, cause2=2)

替换为

method_to_use(model, {"cause1": 2, "cause2": 2}, "output1") 

演示 1

如果捕获组 4 为空,则将匹配替换为

method_to_use(model, {"$2": $3}, "$1")

这会导致字符串

What is P(output2|cause3=2)

替换为

method_to_use(model, {"cause3": 2}, "output2")

演示 2

请注意,两个链接处的正则表达式是等价的,唯一的区别是在 Demo 1 中,我以自由间距模式表达了正则表达式,这允许它是自文档化的。

除了替换整个字符串之外,当然可以简单地从捕获组的值中形成新字符串。如果这是^.*P在正则表达式的开头完成,则可以将其更改为 simple P

正则表达式引擎执行以下操作。

^             # match beginning of line
.*P\(         # match 0+ chars then '|('      
([^|]+)       # save 1+ chars except '|' in cap grp 1 (output)    
\|            # match ':'
([^=]+)       # save 1+ chars except '=' in cap grp 2 (causeA)
=             # match '='
(\d+)         # save 1+ digits in cap grp 3 (causeAval)
(?:           # begin non-cap grp
  ,\ +        # match ',' then 1+ spaces
  ([^=]+)     # match 1+ chars except '=' in cap grp 4 (causeB)   
  =           # match '='
  (\d+)       # match 1+ digits in cap grp 5 (causeBval)
)?            # end non-cap grp and make it optional  
\)            # match ')'
$             # match end of line

推荐阅读