如何使用正则表达式匹配从A到B的任何内容,其中B不在C之前

时间:2015-06-02 00:05:29

标签: c# asp.net regex escaping

我很难用这个。首先,这是我匹配的字符串的难点部分:

"a \"b\" c"

我想从中提取的内容如下:

a \"b\" c

当然,这只是一个来自较大字符串的子字符串,但其他一切都按预期工作。问题是使正则表达式忽略使用反斜杠转义的引号。

我已经研究了各种方法,但没有任何方法能让我得到正确的结果。我最近的尝试看起来像这样:

"((\"|[^"])+?)"

在各种在线测试中,它的工作方式应该是这样 - 但是当我构建我的ASP.NET页面时,它会在第一次切断时“,只留下一个字母,空格和反斜杠。

上述模式背后的逻辑是捕获所有“非”或“非”的实例。我希望这会搜索\“,确保首先找到它们 - 但我感觉这被表达式的第二部分覆盖,只有1个单字符。单个反斜杠不匹配2个字符( \“),但它将匹配为非”。从那里,下一个字符将是一个“,匹配完成。 (这只是我假设我的模式失败的假设。)

关于这个的任何指针?我在正则表达式中尝试过使用“look”方法的各种组合,但我并没有真正得到任何结果。我也觉得这就是我需要的。

2 个答案:

答案 0 :(得分:1)

原始答案

要匹配a \"b\" c之类的字符串,您需要使用以下正则表达式声明:

(?:\\"|[^"])+
var rx = Regex(@"(?:\\""|[^""])+");

请参阅RegexStorm demo

这是IDEONE demo

var str = "a \\\"b\\\" c";
Console.WriteLine(str);
var rx = new Regex(@"(?:\\""|[^""])+");
Console.WriteLine(rx.Match(str).Value);

请注意字符串文字前面的@,它允许我们使用 verbatim 字符串文字,我们必须使用双引号来匹配文字引号并使用单个转义斜杠而不是double。这使得正则表达式更易于阅读和维护。

如果要匹配输入字符串中的任何转义实体,可以使用:

var rx = new Regex(@"[^""\\]*(?:\\.[^""\\]*)*");

See demo on RegexStorm

更新

要匹配引用的字符串,只需在模式周围添加引号:

var rx = new Regex(@"""(?<res>[^""\\]*(?:\\.[^""\\]*)*)""");

这种模式比Tim Long建议的正则表达式产生更好的性能,请参阅RegexHero测试结果:

enter image description here

答案 1 :(得分:1)

以下表达式对我有用:

"(?<Result>(\\"|.)*)"

表达式匹配如下:

  • 开场引文(文字"
  • 命名捕获(?<name>pattern),包括:
    • 文字*或(\")任何单个字符(|
    • 零次或多次出现.
  • 最终结束语(文字"

请注意,*(零或更多)量词是非贪心的,因此最终引用与文字"匹配,而不是&#34;任何单个字符&#34; .部分。

我使用ReSharper 9内置的正则表达式验证器来开发表达式并验证结果:

ReSharper "Validate Regular Expression" feature

我使用了&#34; Explicit Capture&#34;减少输出中的残差的选项(RegexOptions.ExplicitCapture)。

需要注意的一点是,我匹配整个字符串,但我只是捕获子字符串,使用名为capture 的。使用命名捕获是获得所需结果的非常有用的方法。在代码中,它可能看起来像这样:

    static string MatchQuotedString(string input)
        {
        const string pattern = @"""(?<Result>(\\""|.)*)""";
        const RegexOptions options = RegexOptions.ExplicitCapture;
        Regex regex = new Regex(pattern, options);
        var matches = regex.Match(input);
        var substring = matches.Groups["Result"].Value;
        return substring;
        }

优化:如果您计划大量使用正则表达式,可以将其分解为字段并使用RegexOptions.Compiled选项,这会预先编译表达式并以更长的代价为您提供更快的吞吐量初始化。