正则表达式:匹配未闭合的双引号

Lao*_*jin 5 .net regex

我想匹配所有未闭合的双引号。

基本上,如果双引号的数量为偶数,则获取最后一个双引号,或者如果双引号的数量为偶数,则不匹配任何内容。

考虑这个宏伟的代码块:

Input -> Match?
===============
"testy" --> NO MATCH
"ack... --> Match "
"oh my" and "oy my" and " pp --> Match last "
do match " this --> Match "
more "testy" "test --> Match last "
more "testy" test --> NO MATCH
Run Code Online (Sandbox Code Playgroud)

这里的答案不起作用:
正则表达式匹配双引号,但不是双引号对
最有希望的是:".*?"(*SKIP)(*F)|"但这不适用于.NET。

我知道这里可以使用非正则表达式,但我很好奇它是如何完成的......

我的实现没有正则表达式 - 我想这没问题:

if (searchText.IndexOf('"') > -1)
{
    int quoteCount = searchText.Count(x => x == '"');
    if (quoteCount % 2 != 0)
    {
        searchText = searchText.Insert(searchText.LastIndexOf('"'), "\\");
    }
}
Run Code Online (Sandbox Code Playgroud)

Luc*_*ski 2

.NET 具有可供您利用的可变长度lookbehind。

(?<=^(?>(?:[^"]*"){2})*[^"]*)"(?=[^"]*?$)
Run Code Online (Sandbox Code Playgroud)

演示

为了演示,我将 替换为 ,[^"][^"\n]独立考虑每一行。

想法是这样的:

  • 匹配"
  • 确保它是最后一个:(?=[^"]*?$)
  • 确保它前面有偶数个"(?<=^(?>(?:[^"]*"){2})*[^"]*) 向后读取(在 .NET Lookbehind 中向后进行匹配),我们得到:
    • [^"]*
    • 然后匹配[^"]*"偶数次 ( {2})
    • 然后匹配字符串的开头^

原子组可以防止灾难性的回溯。