C# 为啥我的 RegEx 不匹配?这个真的很简单

Posted

技术标签:

【中文标题】C# 为啥我的 RegEx 不匹配?这个真的很简单【英文标题】:C# Why isn't my RegEx matching? This one is really simpleC# 为什么我的 RegEx 不匹配?这个真的很简单 【发布时间】:2021-09-03 10:25:41 【问题描述】:

我已经尝试了几个版本的多少个“\”来匹配 ()。模式需要一加一才能在字符串中得到它。

--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);
    

【问题讨论】:

这不是笔误,也不是非repro,问题是代码的匹配部分不能改,选项不能去掉。必须了解正则表达式选项的工作原理以及它们如何影响模式,这样才能解决问题。 【参考方案1】:

问题在于searchOptions,因为RegexOptions.IgnorePatternWhitespace 在模式格式中生成空格,编译正则表达式对象时,所有空格字符都会从模式中删除。 RegexOptions.Multiline 是多余的,这里可以去掉。

既然你说你不能对代码做太多改动,也不能删除searchOptions,你需要在模式开始处使用(?-x)内联修饰符去激活RegexOptions.IgnorePatternWhitespace选项效果。

这是工作代码:

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

或者,您可以转义所有文字空白字符

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

请注意,我从正则表达式模式中删除了外部捕获括号,并在替换模式中删除了 $1$&(一个完整的匹配反向引用)。

见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);

输出:


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

#

【讨论】:

谢谢,但是这将被传递到更大的系统中,因此必须保留现有的搜索选项。如果空间是精确的,多行是多余的,那为什么会被破坏? @B.McKee 您可以在模式本身中覆盖这些选项。我在第一段中解释了为什么会出现问题:“问题在于searchOptions,因为RegexOptions.IgnorePatternWhitespace 在模式格式中生成空格,编译正则表达式对象时,所有空格字符都从模式中删除"

以上是关于C# 为啥我的 RegEx 不匹配?这个真的很简单的主要内容,如果未能解决你的问题,请参考以下文章

当 regex101 匹配时,RegEx C# 不匹配

为啥这个正则表达式模式不匹配? [复制]

C# Regex.Replace 匹配相同数量的字符

如何在 C# 中与 Regex Class 匹配我部分知道的字符串?

为啥我的 reg ex 不捕获第二行和后续行?

C# - 正则表达式 - 替换不匹配的字符