匹配(和替换)字符串中的文本组

时间:2010-05-25 20:48:54

标签: regex replace

我有以下格式的字符串:

blah IIF((doc.PostTypeId == 1),(Parse(doc.Id)> 1000),(doc.ParentId> 1000)) blah

我希望将其转换为:

blah (doc.PostTypeId == 1?Parse(doc.Id)> 1000:doc.ParentId> 1000) blah

到目前为止,我正在使用以下正则表达式字符串进行匹配

IIF\((?<one>[^,]*?),\ (?<two>[^,]*?),\ (?<three>[^,]*)\)

但是我在平衡所有括号时遇到了问题,是否有更好的方法或正则表达式是错误的工具呢?

1 个答案:

答案 0 :(得分:1)

通常,正则表达式无法正确处理平衡括号,因为这样做需要计算嵌套的深度,这可能是任意深度的,而正则表达式只能存储有限数量的状态(一般来说)。

那就是说,我会假设你所做的改变没有括号嵌套比例如三或四深的嵌套 - 在这种情况下它变得可能。以下是如何构建它:

很容易匹配一个没有括号的序列:

EXPR0:  [^()]*

我们可以用它来创建一个与括号中的单个非嵌套表达式匹配的正则表达式:

PAREN1:   \(EXPR0\)

包含多达一级括号的表达式是什么?好吧,这只是PAREN1与非括号字符的混合:

EXPR1:    (?:PAREN1|EXPR0)*

鉴于此,我们当然可以将括号中的平衡表达式与最多一层嵌套进行匹配:

PAREN2:    \(EXPR1\)

我们可以扩展以匹配任何平衡表达式,以相同的方式匹配不超过两个()的级别

EXPR2: (?:PAREN2|EXPR0)*

等等:

PAREN3:    \(EXPR2\)
EXPR3:     (?:PAREN3|EXPR0)
PAREN4:    \(EXPR3\)
...

然后你可以使用它来构建你想要做的替换的匹配 - 这就是:

IIF\(?<one>EXPR5),(?<two>EXPR5),(?<three>EXPR5)\)

(实际上你需要调整一些东西,以便EXPR5表达式与无表达的逗号相匹配,但是我应该明白如何做到这一点我希望:)

当然,值得编写一个简短的一次性程序来生成所需的r.e.而不是手动构建它!