我很难用这个。首先,这是我匹配的字符串的难点部分:
"a \"b\" c"
我想从中提取的内容如下:
a \"b\" c
当然,这只是一个来自较大字符串的子字符串,但其他一切都按预期工作。问题是使正则表达式忽略使用反斜杠转义的引号。
我已经研究了各种方法,但没有任何方法能让我得到正确的结果。我最近的尝试看起来像这样:
"((\"|[^"])+?)"
在各种在线测试中,它的工作方式应该是这样 - 但是当我构建我的ASP.NET页面时,它会在第一次切断时“,只留下一个字母,空格和反斜杠。
上述模式背后的逻辑是捕获所有“非”或“非”的实例。我希望这会搜索\“,确保首先找到它们 - 但我感觉这被表达式的第二部分覆盖,只有1个单字符。单个反斜杠不匹配2个字符( \“),但它将匹配为非”。从那里,下一个字符将是一个“,匹配完成。 (这只是我假设我的模式失败的假设。)
关于这个的任何指针?我在正则表达式中尝试过使用“look”方法的各种组合,但我并没有真正得到任何结果。我也觉得这就是我需要的。
答案 0 :(得分:1)
要匹配a \"b\" c
之类的字符串,您需要使用以下正则表达式声明:
(?:\\"|[^"])+
var rx = Regex(@"(?:\\""|[^""])+");
这是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(@"[^""\\]*(?:\\.[^""\\]*)*");
要匹配引用的字符串,只需在模式周围添加引号:
var rx = new Regex(@"""(?<res>[^""\\]*(?:\\.[^""\\]*)*)""");
这种模式比Tim Long建议的正则表达式产生更好的性能,请参阅RegexHero测试结果:
答案 1 :(得分:1)
以下表达式对我有用:
"(?<Result>(\\"|.)*)"
表达式匹配如下:
"
)(?<name>pattern)
,包括:
*
或(\"
)任何单个字符(|
).
"
)请注意,*
(零或更多)量词是非贪心的,因此最终引用与文字"
匹配,而不是&#34;任何单个字符&#34; .
部分。
我使用ReSharper 9内置的正则表达式验证器来开发表达式并验证结果:
我使用了&#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
选项,这会预先编译表达式并以更长的代价为您提供更快的吞吐量初始化。