具有特定单词边界的正则表达式
Regular expression with specific word boundary
假设我有一个
类型的字符串
(Price+Discounted_Price)*2-Max.Price
和一个包含每个元素要替换的内容的字典
Price: A1 Discounted_Price: A2 Max.Price:A3
我怎样才能准确地替换每个短语,而不触及另一个。意思是搜索 Price
不应修改 Discounted_Price
中的 Price
。结果应该是 (A1+A2)*2-A3
而不是 (A1+Discounted_A1) - Max.A1
或其他任何东西
谢谢。
对于单词边界,你可以使用\b
使用:\bPrice\b
但这将取代 Max.Price 中的价格。
也许您想使用常规字符串替换为:
"Price+" --> A1 + "+"
示例:
string test = "(Price+Discounted_Price)*2-Max.Price";
string a1 = "7";
string a2 = "3";
string a3 = "4";
test = test.Replace("(Price", "(" + a1);
test = test.Replace("Discounted_Price", a2);
test = test.Replace("Max.Price", a3);
结果:
测试是:(7+3)*2-4
如果您的变量可以包含 alphanumeric/underscore/dot 个字符,您可以将它们与 [\w.]+
正则表达式模式匹配,并添加包含 .
:
的边界
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
public class Test
{
public static void Main()
{
var s = "(Price+Discounted_Price)*2-Max.Price";
var dct = new Dictionary<string, string>();
dct.Add("Price", "A1");
dct.Add("Discounted_Price", "A2");
dct.Add("Max.Price","A3");
var res = Regex.Replace(s, @"(?<![\w.])[\w.]+(?![\w.])", // Find all matches with the regex inside s
x => dct.ContainsKey(x.Value) ? // Does the dictionary contain the key that equals the matched text?
dct[x.Value] : // Use the value for the key if it is present to replace current match
x.Value); // Otherwise, insert the match found back into the result
Console.WriteLine(res);
}
}
如果匹配前面有单词或点字符,则 (?<![\w.])
负向后视将导致匹配失败,如果后跟单词或字符,则 (?![\w.])
负向后视将导致匹配失败点字符。
请注意 [\w.]+
允许在前导和尾随位置使用点,因此,您可能希望将其替换为 \w+(?:\.\w+)*
并用作 @"(?<![\w.])\w+(?:\.\w+)*(?![\w.])"
.
更新
由于您已经将要替换的关键字提取为列表,因此您需要使用不包括点的更复杂的词边界:
var listAbove = new List<string> { "Price", "Discounted_Price", "Max.Price" };
var result = s;
foreach (string phrase in listAbove)
{
result = Regex.Replace(result, @"\b(?<![\w.])" + Regex.Escape(phrase) + @"\b(?![\w.])", dct[phrase]);
}
假设我有一个
类型的字符串(Price+Discounted_Price)*2-Max.Price
和一个包含每个元素要替换的内容的字典
Price: A1 Discounted_Price: A2 Max.Price:A3
我怎样才能准确地替换每个短语,而不触及另一个。意思是搜索 Price
不应修改 Discounted_Price
中的 Price
。结果应该是 (A1+A2)*2-A3
而不是 (A1+Discounted_A1) - Max.A1
或其他任何东西
谢谢。
对于单词边界,你可以使用\b 使用:\bPrice\b
但这将取代 Max.Price 中的价格。
也许您想使用常规字符串替换为:
"Price+" --> A1 + "+"
示例:
string test = "(Price+Discounted_Price)*2-Max.Price";
string a1 = "7";
string a2 = "3";
string a3 = "4";
test = test.Replace("(Price", "(" + a1);
test = test.Replace("Discounted_Price", a2);
test = test.Replace("Max.Price", a3);
结果:
测试是:(7+3)*2-4
如果您的变量可以包含 alphanumeric/underscore/dot 个字符,您可以将它们与 [\w.]+
正则表达式模式匹配,并添加包含 .
:
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
public class Test
{
public static void Main()
{
var s = "(Price+Discounted_Price)*2-Max.Price";
var dct = new Dictionary<string, string>();
dct.Add("Price", "A1");
dct.Add("Discounted_Price", "A2");
dct.Add("Max.Price","A3");
var res = Regex.Replace(s, @"(?<![\w.])[\w.]+(?![\w.])", // Find all matches with the regex inside s
x => dct.ContainsKey(x.Value) ? // Does the dictionary contain the key that equals the matched text?
dct[x.Value] : // Use the value for the key if it is present to replace current match
x.Value); // Otherwise, insert the match found back into the result
Console.WriteLine(res);
}
}
如果匹配前面有单词或点字符,则 (?<![\w.])
负向后视将导致匹配失败,如果后跟单词或字符,则 (?![\w.])
负向后视将导致匹配失败点字符。
请注意 [\w.]+
允许在前导和尾随位置使用点,因此,您可能希望将其替换为 \w+(?:\.\w+)*
并用作 @"(?<![\w.])\w+(?:\.\w+)*(?![\w.])"
.
更新
由于您已经将要替换的关键字提取为列表,因此您需要使用不包括点的更复杂的词边界:
var listAbove = new List<string> { "Price", "Discounted_Price", "Max.Price" };
var result = s;
foreach (string phrase in listAbove)
{
result = Regex.Replace(result, @"\b(?<![\w.])" + Regex.Escape(phrase) + @"\b(?![\w.])", dct[phrase]);
}