1

I'm just beginning to use Regex so bear with my terminology. I have a regex pattern that is working properly on a string. The string could be in the format "text [pattern] text". Therefore, I also have a regex pattern that negates the first pattern. If I print out the results from each of the matches everything is shown correctly.

The problem I'm having is I want to add text into the string and it changes the index of matches in a regex MatchCollection. For example, if I wanted to enclose the found match in "td" match "/td"" tags I have the following code:

Regex r = new Regex(negRegexPattern, RegexOptions.IgnoreCase | RegexOptions.Singleline);
            MatchCollection mc = r.Matches(text);
            if (mc.Count > 0)
            {
                for (int i = 0; i < mc.Count; i++)
                {
                    text = text.Remove(mc[i].Index, mc[i].Length);
                    text = text.Insert(mc[i].Index, "<td>" + mc[i].Value + "</td>");
                }                
            }

This works great for the first match. But as you'd expect the mc[i].Index is no longer valid because the string has changed. Therefore, I tried to search for just a single match in the for loop for the amount of matches I would expect (mc.Count), but then I keep finding the first match.

So hopefully without introducing more regex to make sure it's not the first match and with keeping everything in one string, does anybody have any input on how I could accomplish this? Thanks for your input.

Edit: Thank you all for your responses, I appreciate all of them.

2
  • Just a small comment. You don't need the if(mc.Count > 0) block. If there are no items in the collection, it won't enter the for loop anyway. Commented Jan 23, 2009 at 20:22
  • An example string of what you actually have, and what you want to have might be useful. I have the not-so-unwarranted feeling that regex are the wrong tool for your task. Commented Jan 23, 2009 at 20:27

5 Answers 5

3

It can be as simple as:-

  string newString = Regex.Replace("abc", "b", "<td>${0}</td>");

Results in a<td>b</td>c.

In your case:-

Regex r = new Regex(negRegexPattern, RegexOptions.IgnoreCase | RegexOptions.Singleline);
text = r.Replace(text, "<td>${0}</td>");

Will replace all occurance of negRegexPattern with the content of that match surrounded by the td element.

Sign up to request clarification or add additional context in comments.

Comments

2

Although I agree that the Regex.Replace answer above is the best choice, just to answer the question you asked, how about replacing from the last match to the first. This way your string grows beyond the "previous" match so the earlier matches indexes will still be valid.

for (int i = mc.Count - 1; i > 0; --i)

Comments

1
   static string Tabulate(Match m) 
   {
      return "<td>" + m.ToString() + "</td>";
   }

   static void Replace() 
   {
      string text = "your text";
      string result = Regex.Replace(text, "your_regexp", new MatchEvaluator(Tabulate));
   }

Comments

1

You can try something like this:

Regex.Replace(input, pattern, match =>
{
   return "<tr>" + match.Value + "</tr>";
});

Comments

-2

Keep a counter before the loop starts, and add the amount of characters you inserted every time. IE:

            Regex r = new Regex(negRegexPattern, RegexOptions.IgnoreCase | RegexOptions.Singleline);
            MatchCollection mc = r.Matches(text);

                int counter = 0;
                for (int i = 0; i < mc.Count; i++)
                {
                    text = text.Remove(mc[i].Index + counter, mc[i].Length);
                    text = text.Insert(mc[i].Index + counter, "<td>" + mc[i].Value + "</td>");
                    counter += ("<td>" +  "</td>").Length;
                }

I haven't tested this, but it SHOULD work.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.