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

时间:2015-09-02 15:58:33

标签: .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

这里的答案不起作用:
Regex match double quote, but not pair of double quotes
最有希望的是:".*?"(*SKIP)(*F)|"但这对.NET不起作用。

我知道这里有非正则表达式,但我很好奇它是如何做到的......

我没有正则表达式的实现 - 我猜是好的:

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

2 个答案:

答案 0 :(得分:2)

.NET具有可以利用的可变长度的lookbehinds。

(?<=^(?>(?:[^"]*"){2})*[^"]*)"(?=[^"]*?$)

Demo

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

以下是这个想法:

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

原子团防止了灾难性的回溯。

答案 1 :(得分:2)

那样“简单”
^[^\"]*(\"[^\"]*\"[^\"]*)*(\")[^\"]*$

我只针对“经典”正则表达式解释器进行了测试,并且它没有使用任何古怪的技巧,因此无论平台如何都应该完全兼容。

它的作用基本上是:

  1. 匹配字符串的开头(行)
  2. 匹配任何(可能是0)个非“字符”
  3. 匹配任何(可能是0)次:
    • “character
    • 任意数量的非“字符”
    • “character
    • 任意数量的非“字符”
  4. 匹配“字符(这将是您要查找的组)
  5. 匹配任意数量的非“字符”
  6. 匹配字符串的结尾