首页 文章

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

提问于
浏览
3

我想匹配所有未关闭的双引号 .

基本上,如果有一个双引号,或者如果有双引号的话,则不能匹配任何内容的最后一个双引号 .

考虑这个宏伟的代码块:

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 回答

  • 2

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

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

    Demo

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

    这是个主意:

    • 匹配 "

    • 确保它是最后一个: (?=[^"]*?$)

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

    • [^"]*

    • 然后匹配 [^"]*" 偶数次( {2}

    • 然后匹配字符串 ^ 的开头

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

  • 2

    像“简单”这样的东西怎么样

    ^[^\"]*(\"[^\"]*\"[^\"]*)*(\")[^\"]*$
    

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

    它的作用基本上是:

    • 匹配字符串的开头(行)

    • 匹配任何(可能是0)个非“字符”

    • 匹配任何(可能是0)次:

    • “性格

    • 任意数量的非“字符

    • “性格

    • 任意数量的非“字符

    • 匹配“字符(这将是您要查找的组)

    • 匹配任意数量的非“字符”

    • 匹配字符串的结尾

相关问题