[Solved] Regex in C# – how I replace only one specific group in Match?

I’m parsing a text using C# regex. I want to replace only one specific group in for each match. Here how I’m doing it:

void Replace(){
  string newText = Regex.Replace(File.ReadAllText(sourceFile), myRegex, Matcher, RegexOptions.Singleline);
  //.......   
}

void string Matcher(Match m){
  // how do I replace m.Groups[2] with "replacedText"?
  return ""; // I want to return m.Value with replaced m.Group[2]
}

Solution #1:

This should do it:

string Matcher(Match m)
{
    if (m.Groups.Count < 3)
    {
        return m.Value;
    }

    return string.Join("",  m.Groups
                             .OfType<Group>() //for LINQ
                             .Select((g, i) => i == 2 ? "replacedText" : g.Value)
                             .Skip(1) //for Groups[0]
                             .ToArray());
}

Example: http://rextester.com/DLGVPA38953

EDIT: Although the above is the answer to your question as written, you may find zero-width lookarounds simpler for your actual scenario:

Regex.Replace(input, @"(?<=e)l+(?=o)", replacement)

Example: http://rextester.com/SOWWS24307

Respondent: Alan Coromano

Solution #2:

You can use MatchEvaluator:
Try This.

var replaced = Regex.Replace(text, pattern, m => m.Groups[1] + "AA" + m.Groups[3]);

I found one post in stackoverflow related to this: watch This

Respondent: Justin Morgan

Solution #3:

How about this?

    static string Matcher(Match m)
    {
        var group = m.Groups[2];
        var startIndex = group.Index - m.Index;
        var length = group.Length;
        var original = m.Value;
        var prior = original.Substring(0, startIndex);
        var trailing = original.Substring(startIndex + length);
        return string.Concat(prior, "replacedText", trailing);
    }
Respondent: Bhavik Patel

Solution #4:

Regex.Replace will always replace everything that the provided regex has matched.

You have two possibilities:

  1. Match only what you want to replace

    or

  2. Insert the parts of the original string which has been matched, but should be kept, into the replacement string, using capturing groups.

You provided not enough information to answer your question more specific. E.g. do you really need a MatchEvaluator? This is only needed, if you want to provide an individual replacement string for each match.

Respondent: mlorbetske

Solution #5:

    private string ReplaceText(string originalText)
    {
        string replacedText = null;

        Regex regEx = new Regex("[your expression here]");

        Match match = regEx.Match(originalText);

        if (match.Success)
        {
            Group matchGroup = match.Groups[2];

            //[first part of original string] + [replaced text] + [last part of original string]
            replacedText =
                $"{originalText.Substring(0, matchGroup.Index)}[Your replaced string here]{originalText.Substring(matchGroup.Index + matchGroup.Length)}";

        }
        else
            replacedText = originalText;

        return replacedText;
    }
Respondent: stema

Solution #6:

The below code will take a match and construct a replacement string based on the groupValues collection. This collection specifies a Group index and the text to replace it’s value with.

Unlike other solutions, it does not require the entire match to be contained in groups, only the parts of the match that you want to have in groups.

public static string ReplaceGroups(Match match, Dictionary<int, string> groupValues)
{
    StringBuilder result = new StringBuilder();

    int currentIndex = 0;
    int offset = 0;

    foreach (KeyValuePair<int, string> replaceGroup in groupValues.OrderBy(x => x.Key))
    {
        Group group = match.Groups[replaceGroup.Key];

        if (currentIndex < group.Index)
        {
            result.Append(match.Value.Substring(currentIndex, group.Index - match.Index - currentIndex));
        }

        result.Append(replaceGroup.Value);

        offset += replaceGroup.Value.Length - group.Length;
        currentIndex = group.Index - match.Index + group.Length;
    }

    return result.ToString();
}
Respondent: Raymond

The answers/resolutions are collected from stackoverflow, are licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0 .

Leave a Reply

Your email address will not be published.