问题
我需要用百分号 ('%') 替换所有星号 ('*')。方括号中的星号应忽略。
示例
[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/