c# - 正则表达式跳过模式

标签 c# regex

问题

我需要用百分号 ('%') 替换所有星号 ('*')。方括号中的星号应忽略。

示例

    [Test]
    public void Replace_all_asterisks_outside_the_square_brackets()
    {
        var input = "Hel[*o], w*rld!";
        var output = Regex.Replace(input, "What_pattern_should_be_there?", "%")

        Assert.AreEqual("Hel[*o], w%rld!", output));
    }

最佳答案

尝试使用前瞻:

\*(?![^\[\]]*\])

这里有一个更强大的解决方案,它处理了 [] block 更好,甚至逃脱了\[字符:

string text = @"h*H\[el[*o], w*rl\]d!";
string pattern = @"
\\.                 # Match an escaped character. (to skip over it)
|
\[                  # Match a character class 
    (?:\\.|[^\]])*  # which may also contain escaped characters (to skip over it)
\]
|
(?<Asterisk>\*)     # Match `*` and add it to a group.
";

text = Regex.Replace(text, pattern,
    match => match.Groups["Asterisk"].Success ? "%" : match.Value,
    RegexOptions.IgnorePatternWhitespace);

如果您不关心转义字符,您可以将其简化为:

\[          # Skip a character class
    [^\]]*  # until the first ']'
\]
|
(?<Asterisk>\*)

可以不用注释写成:@"\[[^\]]*\]|(?<Asterisk>\*)" .

要了解其工作原理,我们需要了解 Regex.Replace 的工作原理:对于字符串中的每个位置,它都会尝试匹配正则表达式。如果失败,它会移动一个字符。如果成功,它将移动到整场比赛。
在这里,我们有 [...] 的虚拟匹配项 block ,所以我们可以跳过我们不想替换的星号,只匹配孤独的星号。该决定是在一个回调函数中做出的,该函数检查是否 Asterisk是否匹配。

关于c# - 正则表达式跳过模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5153980/

相关文章:

python - 将缩进代码向左移动,删除前导标签

regex - 使用正则表达式匹配字符串中的 <br> 或 <br/>

c# - 静态类的竞争条件?

c# - gridview 模型绑定(bind)和排序

c# - 仅当 xml 数据从 C# 传递到存储过程时,才在存储过程中使用删除表查询

c# - 访问 5 字节结构比 8 字节慢得多

javascript - SetTimeOut 和回发发生后如何关闭模态

c# - 返回正则表达式中的所有数字

正则表达式捕获重复组中不需要的字符

java - 使用正则表达式替换全部不替换完整结果