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

时间:2017-06-26 11:09:16

标签: c# .net regex .net-4.0

我有简单的字符串替换,它寻找特定的单词并用其他东西替换 即如果我有一个关键 - 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。请访问www.something.com/bla/something" ,最终为

" boo boo test test1 test3。请访问www.something.com/boo/something"

(此内容显示在html viwer中)

这里我想跳过url中的替换,这样它就可以替换所有内容而不是url。这是可能的吗

1 个答案:

答案 0 :(得分:1)

是的,您可以匹配看起来像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.Key Regex.Escape(obj.Key)中潜在的特殊字符。

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

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

所以,我推荐像

这样的东西
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