Let's say I have a string of type
假设我有一个类型的字符串
(Price+Discounted_Price)*2-Max.Price
(价格+ Discounted_Price)* 2-Max.Price
and a dictionary containing what to replace for each element
以及一个字典,包含每个元素的替换内容
Price: A1 Discounted_Price: A2 Max.Price:A3
价格:A1 Discounted_Price: A2 Max.Price:A3
How can I replace exactly each phrases, without touching the other. Meaning search for Price
should not modify Price
in Discounted_Price
. The result should be (A1+A2)*2-A3
and not (A1+Discounted_A1) - Max.A1
or anything else
我如何能准确地替换每一个短语,而不触及另一个短语。意思是搜索价格不应该在折扣价格中修改价格。结果应该是(A1+A2)*2-A3,而不是(A1+Discounted_A1) - Max。A1或其他
Thank you.
谢谢你!
2 个解决方案
#1
2
If your variables can consist of alphanumeric/underscore/dot characters, you can match them with [\w.]+
regex pattern, and add boundaries that include .
:
如果您的变量可以由字母数字/下划线/点字符组成,您可以使用[\w]匹配它们。+ regex模式,并添加包含的边界。
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);
}
}
See the IDEONE demo
看到IDEONE演示
The (?<![\w.])
negative lookbehind fails the match if the match is preceded with a word or a dot char, and the (?![\w.])
negative lookahead will fail the match if it is followed with a word or dot char.
如果匹配之前有一个单词或一个点字符,那么(?! !)负的lookahead将失败匹配,如果后面跟着一个单词或点字符,则负的lookahead将失败匹配。
Note that [\w.]+
allows a dot in the leading and trailing positions, thus, you might want to replace it with \w+(?:\.\w+)*
and use as @"(?<![\w.])\w+(?:\.\w+)*(?![\w.])"
.
注意,[\ w。]+允许在前后的位置点,因此,您可能想要换成\ w +(?:\ \ w +)*和使用@”(? < !(\ w。))\ w +(?:\ \ w +)*(? ![\ w。])”。
UPDATE
更新
Since you have already extracted the keywords to replace as a list, you need to use a more sophisticated word boundary excluding dots:
由于您已经提取了要替换为列表的关键字,所以需要使用更复杂的词边界,不包括点:
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]);
}
See IDEONE demo.
看到IDEONE演示。
#2
0
For word boundaries, you can use \b Use: \bPrice\b
对于单词边界,你可以使用\b用法:\bPrice\b
But this will replace Price in Max.Price.
但这将取代价格。
Maybe you want to use regular string replace with:
也许你想用正则字符串替换为:
"Price+" --> A1 + "+"
“价格+”——> A1 +“+”
Example:
例子:
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);
Result:
结果:
test is: (7+3)*2-4
测试是:(7 + 3)* 2 - 4
#1
2
If your variables can consist of alphanumeric/underscore/dot characters, you can match them with [\w.]+
regex pattern, and add boundaries that include .
:
如果您的变量可以由字母数字/下划线/点字符组成,您可以使用[\w]匹配它们。+ regex模式,并添加包含的边界。
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);
}
}
See the IDEONE demo
看到IDEONE演示
The (?<![\w.])
negative lookbehind fails the match if the match is preceded with a word or a dot char, and the (?![\w.])
negative lookahead will fail the match if it is followed with a word or dot char.
如果匹配之前有一个单词或一个点字符,那么(?! !)负的lookahead将失败匹配,如果后面跟着一个单词或点字符,则负的lookahead将失败匹配。
Note that [\w.]+
allows a dot in the leading and trailing positions, thus, you might want to replace it with \w+(?:\.\w+)*
and use as @"(?<![\w.])\w+(?:\.\w+)*(?![\w.])"
.
注意,[\ w。]+允许在前后的位置点,因此,您可能想要换成\ w +(?:\ \ w +)*和使用@”(? < !(\ w。))\ w +(?:\ \ w +)*(? ![\ w。])”。
UPDATE
更新
Since you have already extracted the keywords to replace as a list, you need to use a more sophisticated word boundary excluding dots:
由于您已经提取了要替换为列表的关键字,所以需要使用更复杂的词边界,不包括点:
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]);
}
See IDEONE demo.
看到IDEONE演示。
#2
0
For word boundaries, you can use \b Use: \bPrice\b
对于单词边界,你可以使用\b用法:\bPrice\b
But this will replace Price in Max.Price.
但这将取代价格。
Maybe you want to use regular string replace with:
也许你想用正则字符串替换为:
"Price+" --> A1 + "+"
“价格+”——> A1 +“+”
Example:
例子:
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);
Result:
结果:
test is: (7+3)*2-4
测试是:(7 + 3)* 2 - 4