简体   繁体   English

C# 字符串替换为字典和正则表达式条件

[英]C# String replace with dictionary and Regex condition

I want to replace values of a string with a dictionary that I have but only if they comply a regex condition.我想用我拥有的字典替换字符串的值,但前提是它们符合正则表达式条件。

This is what I have:这就是我所拥有的:

string input = @"A.4 AND ([10] A.4 OR A.4) OR [10]A.4 A.5 [10]A.5";
Dictionary <string, string> dict = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase) {
                                                    {"A.4", "Test"},
                                                    {"A.5", "Test2"},
                                                    };
var output = dict.Aggregate(input, (current, value) => current.Replace(value.Key, value.Value));

//current output = "Test AND ([10] Test OR Test) OR [10]Test Test2 [10]Test2"
//wished output = "Test AND ([10] A.4 OR Test) OR [10]A.4 Test2 [10]A.5"

I don't want to replace the text when there is "[10]" or "[10] " in front of the text.当文本前面有"[10]""[10] "时,我不想替换文本。 I think that I should use a regex or something similar but I don't know how.我认为我应该使用正则表达式或类似的东西,但我不知道如何。

You could use regex to perform the replace operation:您可以使用正则表达式来执行替换操作:

var output = dict.Aggregate(input, (current, sub) => Regex.Replace(current, $@"(?<!\[10\]\s?){Regex.Escape(sub.Key)}", sub.Value));

The negative lookbehind assertion (?<?\[10\]\s?) will ensure the matched term never follows [10] or [10] .否定后向断言(?<?\[10\]\s?)将确保匹配的术语永远不会跟在[10][10]


As Panagiotis Kanavos notes you can skip the Aggregate call completely by passing a delegate that performs a dictionary lookup to Regex.Replace :正如Panagiotis Kanavos 指出的那样,您可以通过将执行字典查找的委托传递给Regex.Replace来完全跳过Aggregate调用:

var replacePattern = $@"(?<!\[10\]\s?)(?:{string.Join('|', dict.Keys.Select(Regex.Escape))})";
var output = Regex.Replace(input, replacePattern, (m) =>  dict[m.Value]);

Regex.Replace has an overload with a delegate that creates replacement values. Regex.Replace具有创建替换值的委托的重载。 If the tags have a pattern, a single regular expression can be used to match them and replace them using the dictionary values.如果标签具有模式,则可以使用单个正则表达式来匹配它们并使用字典值替换它们。

This regex matches tags in the form An where n a number:此正则表达式匹配An形式的标签,其中n是一个数字:

var regex=new Regex(@"(?<!\[10\]\s?)A\.\d+");

var output=regex.Replace(input,match=>dict[match.Value]);

Console.WriteLine(output);

This produces这产生

Test AND ([10] A.4 OR Test) OR [10]A.4 Test2 [10]A.5

(?<....) is a negative lookbehind pattern. (?<....)是一种消极的后视模式。 It matches strings that don't start with the negated pattern.它匹配以否定模式开头的字符串。 (?<?\[10\]\s?) matches strings that don't start with [10] and an optional space. (?<?\[10\]\s?)匹配不以[10]和可选空格开头的字符串。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM