正则表达式替换 - 忽略链接中的内容
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.Key
和 Regex.Escape(obj.Key)
中潜在的特殊字符。
\b(https?://\S+|www\.)
匹配整个单词(因为 \b
是单词边界) http
或 https
然后 ://
和 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。
我有简单的字符串替换功能,它会查找特定的词并替换为其他内容。
即如果我有一个键 - 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.Key
和 Regex.Escape(obj.Key)
中潜在的特殊字符。
\b(https?://\S+|www\.)
匹配整个单词(因为 \b
是单词边界) http
或 https
然后 ://
和 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。