Hello world, hello world

"; string[] terms = new s...">

C # Regex replace replacement string for each match

I have a line like this:

string s = "<p>Hello world, hello world</p>"; string[] terms = new string[] {"hello", "world"}; 

I want to make a replacement on this line so that each word (case insensitive) is matched and replaced with a numbered index index in this way:

 <p> <span id="m_1">Hello</span> <span id="m_2">world</span>, <span id="m_3">hello</span> <span id="m_4">world</span>! </p> 

I tried to do it like this.

 int match = 1; Regex.Replace(s, String.Join("|", String.Join("|", terms.OrderByDescending(s => s.Length) .Select(Regex.Escape))), String.Format("<span id=\"m_{0}\">$&</span>", match++), RegexOptions.IgnoreCase); 

The result looks something like this:

 <p> <span id="m_1">Hello</span> <span id="m_1">world</span>, <span id="m_1">hello</span> <span id="m_1">world</span>! </p> 

Where all identifiers are the same (m_1), because the regular expression does not evaluate ++ for each match, but one for the entire Regex. How do I get around this?

+5
source share
1 answer

All you have to do is convert the replacement argument from the string template to the correspondence analyzer ( m => String.Format("<span id=\"m_{0}\">{1}</span>", match++, m.Value) ):

 string s1 = "<p>Hello world, hello world</p>"; string[] terms = new string[] {"hello", "world"}; var match = 1; s1 = Regex.Replace(s1, String.Join("|", String.Join("|", terms.OrderByDescending(s => s.Length) .Select(Regex.Escape))), m => String.Format("<span id=\"m_{0}\">{1}</span>", match++, m.Value), RegexOptions.IgnoreCase); Console.Write(s1); // => <p><span id="m_1">Hello</span> <span id="m_2">world</span>, <span id="m_3">hello</span> <span id="m_4">world</span></p> 

See a C # demo

+5
source

Source: https://habr.com/ru/post/1266825/


All Articles