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. I think that I should use a regex or something similar but I don't know how.
CodePudding user response:
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]
.
As Panagiotis Kanavos notes you can skip the Aggregate
call completely by passing a delegate that performs a dictionary lookup to Regex.Replace
:
var replacePattern = $@"(?<!\[10\]\s?)(?:{string.Join('|', dict.Keys.Select(Regex.Escape))})";
var output = Regex.Replace(input, replacePattern, (m) => dict[m.Value]);
CodePudding user response:
Regex.Replace has an overload with a delegate that creates replacement values. 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 A.n
where n
a number:
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.