简体   繁体   中英

Why is Regex.Replace not working as expected?

Given the strings "Hello" + "{l}:1" , the following method should only replace the first occurrence of the character l in the left string (any number of characters can be matched here though).

private static string SubtractString(string left, string right)
{
    bool TryReplace(string pattern, out string output)
    {
        var match = Regex.Match(right, pattern);
        if (match.Success)
        {
            output = Regex.Replace(left, $@"{match.Groups[1].Value}{{{match.Groups[2].Value}}}", string.Empty);
            return true;
        }

        output = null;
        return false;
    }
    
    if (TryReplace(@"{(.+)}:([1-9]+|\*{1})", out var result))
        return result;
    
    return TryReplace(@"(.{1}):([1-9]+|\*{1})", out result) ? result : left.Replace(right, string.Empty);
}

The expected output should be Helo but I instead get Heo . The pattern being generated ( $@"{match.Groups[1].Value}{{{match.Groups[2].Value}}}" ) evaluates to l{1} which should only match once.

Using https://regexr.com/6eapt I can only find this behaviour with the global flag enabled which I haven't set in my code.

Any help would be much appreciated, Thanks.

I think this is caused by a confusion created from regexr allowing you to play with JavaScript expressions; they're subtly different to .net ones. By default a JavaScript expression only replaces the first match it comes across whereas Regex.Replace in .net will replace all matches it comes across. Your string of "Hello" and resulting pattern of "l{1}" will find two matches

If you want "just replace the first match" you'll need to switch to using a non static method

        output = new Regex($@"{match.Groups[1].Value}{{{match.Groups[2].Value}}}").Replace(left, string.Empty, 1);
        
    

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM