blender111
blender111

Reputation: 95

Replace Regex match

I have this string:

string coordinates = @"=ZS123, ZS1234 + 36 + Z(56)S45 + 0";

This string must be converted to another string, depending on the values. The regex finds the values I need to make calculations. Regex matches following values: ZS123, ZS1234, Z(56)S45

Regex regexPattern1 = new Regex(@"(Z.*?S(?:\([^)]+\))?(?:\d+)?)");
string coordinates = @"=ZS123, ZS1234 + 36 + Z(56)S45 + 0";
MatchCollection matchCollection = regexPattern1.Matches(coordinates);
        
//Piece by piece the coordinates are replaced by other strings, after a calculation has been done with the matched string
foreach (Match match in matchCollection)
{
    if (match.Value.StartsWith("ZS("))
    {
        //calculations
        string cellIndex =  XY //output 
        coordinates = coordinates.Replace(match.Value, cellIndex);

        //the Match should be replaced with the calculated value(cellindex)
        //but of course this leads to a problem by doing it this way
        // my coordinates string would be now
        //coordinates = XY, XY4 + 36 + Z(56)S45 + 0";
        //it should be:
        //coordinates = XY, ZS1234 + 36 + Z(56)S45 + 0";
        //how to replace the exact match at the right spot once?
    }
    else if (match.Value.StartsWith("Z(") && match.Value.Contains("S("))
    {
        //calculations
        string cellIndex = //output 
        coordinates = coordinates.Replace(match.Value, cellIndex);
    }

   //////else if()
   //////
}

I am a novice in programming, thanks a lot for your help. I hope this is so far understandable

Upvotes: 0

Views: 191

Answers (1)

41686d6564
41686d6564

Reputation: 19641

Instead of using Regex.Matches(), you should use an overload of the Regex.Replace() method that takes a MatchEvaluator argument so that you can do your "calculations" in the method of the MatchEvaluator.

Your code should look something like this:

Regex regEx = new Regex(@"(Z.*?S(?:\([^)]+\))?(?:\d+)?)");
string coordinates = @"=ZS123, ZS1234 + 36 + Z(56)S45 + 0";

string output = regEx.Replace(coordinates, delegate (Match m)
{
    string cellIndex = m.Value;
    if (m.Value.StartsWith("ZS("))
    {
        //calculations
        cellIndex = "Something";
    }
    else if (m.Value.StartsWith("Z(") && m.Value.Contains("S("))
    {
        //calculations
        cellIndex = "Something else";
    }
    // etc.

    return cellIndex;
});

Note that I didn't make any changes to your regex pattern because you haven't provided enough information about what should and shouldn't match. However, let me point something out...

The Z.*?S part will match any number of characters (any characters) between "Z" and "S". So, it will match things like "ZA1@S". It's also the part that is responsible for matching "Z(56)S" in your third expected match and the (?:\([^)]+\))? part is irrelevant here. If your original intention was to only allow parentheses between "Z" and "S", then you probably should use something like the following instead:

Z(?:\([^)]+\))?S(?:\d+)?

Another note is that you might want to review your if conditions as they don't really make sense based on your expected matches. I.e., none of the matches starts with "ZS(" or both starts with "Z(" and contains "S(".

Upvotes: 1

Related Questions