正则表达式 - 没有括号的匹配模式

时间:2016-02-25 08:21:54

标签: c# regex

例如我有这个字符串:

ABCDFFFE[_]XXX[_]O0[_]%[TT]__

我想要做的是,将所有_匹配/更改为?,并将%更改为*,但不是!括号内的那些。最后一件事是删除括号,但我可以通过字符串替换来实现。

所以我的正则表达式之后的输出应该是这样的:

ABCDFFFE[_]XXX[_]O0[_]*[TT]??

并且在替换字符串之后(或者也可以使用正则表达式完成)

ABCDFFFE_XXX_O0_%TT__

提前致谢

2 个答案:

答案 0 :(得分:3)

由于[...]文本无法嵌套,您可以使用以下正则表达式:

(\[[^][]*])|[_%]

请参阅regex demo

它会将[...]个子字节捕获到第1组(以便我们以后可以在替换结果中恢复它们)并匹配_%

在以下代码中使用它:

var s = "ABCDFFFE[_]XXX[_]O0[_]%[TT]__";
var result = Regex.Replace(s, @"(\[[^][]*])|[_%]", m =>
            m.Groups[1].Success ? m.Groups[1].Value : m.Value == "_" ? "?" : "*");

m匹配评估程序块检查组1是否匹配,如果是,则插入m.Groups[1].Value。如果没有,我们会检查m.Value:如果是_,则替换为?(请参阅m.Value == "_" ? "?"),如果不是 - 请替换为*

更新

要获得结果#2,没有[]的字符串,您可以使用

var result = Regex.Replace(te, @"(\[([^][]*)])|[_%]", m =>
            m.Groups[1].Success ? m.Groups[2].Value : m.Value == "_" ? "?" : "*");

模式(\[([^][]*)])|[_%]将整个[...]捕获到组1中,并将其中的内容捕获到组2.如果组1匹配,则组2被初始化,我们可以用{{1 }}

请参阅IDEONE demos for both solutions

答案 1 :(得分:1)

如果你已经知道每个开口支架都有一个右括号(括号是平衡的),你可以测试一个结束括号是否跟随负向前瞻:

var result = Regex.Replace(s, @"[_%](?![^\]\[]*\])", m => m.Value == "_" ? "?" : "*");