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

本文关键字:模式 正则表达式 | 更新日期: 2023-09-27 18:36:17

例如我有这个字符串:

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

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

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

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

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

ABCDFFFE_XXX_O0_%TT__

提前致谢

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

由于[...]文本不能嵌套,因此您可以使用以下正则表达式:

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

查看正则表达式演示

它会将[...]潜台词捕获到第 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,我们可以用 m.Groups[2].Value .

查看两种解决方案的 IDEONE 演示

如果您已经知道每个左括号都有一个右括号(括号是平衡的),则可以测试右括号后面是否没有负面的前瞻:

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