正则表达式替换 - 忽略链接中的内容

Regex replace - Ignore content in links

我有简单的字符串替换功能,它会查找特定的词并替换为其他内容。
即如果我有一个键 - bla 和值 - boo,下面将产生

 var input ="bla bla test test1 test3...";

 foreach (var obj in dictionary)
 {
    inputText = Regex.Replace(inputText, obj.Key, obj.Value); 
 }

var output = "boo boo test test1 test3...";

现在我有 html 作为输入,现在输入可以是

"bla bla test test1 test3. Go to www.something.com/bla/something" 结果是

"boo boo test test1 test3. Go to www.something.com/boo/something"

(此内容显示在 html 浏览器中)

这里我想跳过 url 中的替换,所以它只会替换所有内容,但不会替换 url。有可能吗

是的,您可以匹配看起来像 URL 的子字符串并保留该文本,否则执行替换。

代码看起来像

inputText = Regex.Replace(inputText, $@"\b(https?://\S+|www\.\S+)|{Regex.Escape(obj.Key)}", m =>
                    m.Groups[1].Success ? m.Groups[1].Value : obj.Value); 

请注意,我使用 Regex.Escape 来转义 obj.KeyRegex.Escape(obj.Key) 中潜在的特殊字符。

\b(https?://\S+|www\.) 匹配整个单词(因为 \b 是单词边界) httphttps 然后 :// 和 1+ 非空白字符或 www. 和 1+ 个非空白字符。因此,如果正则表达式匹配 URL,它将被放入 m.Groups[1] 并在匹配评估器中,替换将是相同的 URL 文本,否则,obj.Value将用作替换文本。

不过,这种方法可能还有另一个问题,即,将相同的文本替换两次或更多次。然后,您需要根据您的字典键创建一个带有交替的正则表达式,然后使用匹配评估器根据键匹配获得正确的值。

所以,我推荐

var dct = new Dictionary<string, string>();
dct.Add("bla", "boo");
dct.Add("bla test", "ZZZ");
var pat = $@"\b(https://\S+|www\.\S+)|(?:{string.Join("|",dct.Keys.Select(k => Regex.Escape(k)).OrderByDescending(x => x.Length))})";
// Console.WriteLine(pat); => \b(https://\S+|www\.\S+)|(?:bla\ test|bla)
var input ="bla bla test test1 test3. Go to www.something.com/bla/something";
var output = Regex.Replace(input, pat, m => m.Groups[1].Success ? m.Groups[1].Value : dct[m.Value]); 
Console.Write(output);
// => boo ZZZ test1 test3. Go to www.something.com/bla/something

参见C# demo