1

I've tried several versions of how many "\" to get the ()'s to match. The pattern needs one, plus one to get it in the string.

--fixme.h--

#
_TARGET_VERSION = $(_TARGET_VERSION_GREEN)

#

--Program.cs--

static void Main(string[] args)
{
    var expr = "(_TARGET_VERSION = \\$\\(_TARGET_VERSION_GREEN\\))";
    var repl = "!if 0\n$1\n!endif";

    var content = File.ReadAllText("fixme.h");
    var searchOptions = RegexOptions.IgnorePatternWhitespace | RegexOptions.Multiline;
    var matched = Regex.Match(content, expr, searchOptions);
    if (matched.Success)
    {
        var newContent = Regex.Replace(content, expr, repl, searchOptions);
        File.WriteAllText("fixed.h", newContent);
    }
}
1
  • 1
    This is not a typo, nor is it non-repro, the problem is that the matching part of the code cannot be changed, and the options cannot be removed. One must understand how regex options work and how they effect the pattern so that the problem could be fixed. Commented Jun 18, 2021 at 18:05

1 Answer 1

1

The problem is with the searchOptions as the RegexOptions.IgnorePatternWhitespace makes the whitespace in the pattern formatting, all whitespace chars are removed from the pattern when compiling the regex object. The RegexOptions.Multiline is redundant here can could be removed.

Since you say you can't change the code much and can't remove searchOptions, you need to use the (?-x) inline modifier at the pattern start to deactivate the RegexOptions.IgnorePatternWhitespace option effect.

Here is the working code:

var expr = "(?-x)_TARGET_VERSION = \\$\\(_TARGET_VERSION_GREEN\\)";
var expr = @"(?-x)_TARGET_VERSION = \$\(_TARGET_VERSION_GREEN\)";

Or, you may escape all literal whitespace chars:

var expr = "_TARGET_VERSION\\ =\\ \\$\\(_TARGET_VERSION_GREEN\\)";
var expr = @"_TARGET_VERSION\ =\ \$\(_TARGET_VERSION_GREEN\)";

Note I removed the outer capturing parentheses from the regex pattern and the $1 with $& (a whole match backreference) in the replacement pattern.

See the C# demo online:

var expr = "(?-x)_TARGET_VERSION = \\$\\(_TARGET_VERSION_GREEN\\)";
var repl = "!if 0\n$&\n!endif";
var content = @"#
_TARGET_VERSION = $(_TARGET_VERSION_GREEN)

#";
var searchOptions = RegexOptions.IgnorePatternWhitespace | RegexOptions.Multiline;
var matched = Regex.Match(content, expr, searchOptions);
if (matched.Success)
{
    var newContent = Regex.Replace(content, expr, repl, searchOptions);
    Console.WriteLine(newContent);
}

Output:


#
!if 0
_TARGET_VERSION = $(_TARGET_VERSION_GREEN)
!endif

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

2 Comments

Thank you, however this will be passed into a bigger system, so the existing search options have to stay. If the space is exact and multiline is redundant, then why is it broken?
@B.McKee You can override these options in the pattern itself. I explained why the issue occurs in the first paragraph: "The problem is with the searchOptions as the RegexOptions.IgnorePatternWhitespace makes the whitespace in the pattern formatting, all whitespace chars are removed from the pattern when compiling the regex object"

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.