正则表达式匹配具有偶数引号的字符串

时间:2009-03-20 22:03:28

标签: regex

我想出了:([^"]*["][^"]*["][^"]*)*

除了空字符串外,它适用于所有情况。我认为它会起作用,因为最后一个星号匹配前一个标记或更多次。

有什么想法吗?

如果还有更好的方法,请告诉我并详细解释。

解决方案必须是正则表达式,因为它将被用于需要正则表达式的钩子。

它必须匹配没有引号的字符串,因为零是偶数

5 个答案:

答案 0 :(得分:6)

试试这个表达式:

^(?:[^"]+|"[^"]*")*$

它匹配一个序列,该序列由引号([^"]+)以外的任何字符组成,或者与("[^"]*")之间引用之外的任何字符组成的引号对。 *量词会考虑空字符串。

答案 1 :(得分:4)

你的正则表达式应该匹配完全空的字符串,但不是由单个空格组成的字符串,因为正则表达式声明如果字符串不是完全为空,则需要包含至少一个双引号。这是因为正则表达式中的[“]标记后面没有*。

考虑所需正则表达式的正确方法如下:你想匹配(不带双引号的字符串)后跟(双引号)加(不带双引号的字符串)后跟(双引号)后跟(字符串)没有双引号),然后从第一个'后跟'无限重复开始重复。没有双引号的字符串是[^“] *,所以你得到(为了可读性添加了空格):

[^"]* (" [^"]* " [^"]*)*

如果将其与正则表达式进行比较,则第一个[^“] *已被移动 out 重复。

答案 2 :(得分:2)

似乎regexp不适合这项工作。编辑:但是,你似乎受限于它。鉴于这种约束,这并没有回答你的问题,但如果没有它,它就会很好。

只需迭代你的字符串并计算。例如:

bool hasEvenNumberOfQuotes(const char *str)
{
    bool even = true;

    while(*str != '\0')
    {
        if(*str == '"')
            even = !even;

        ++str;
    }

    return even;
}

答案 3 :(得分:2)

基于你的正则表达式:

([^"]*["][^"]*["][^"]*)*

添加线锚:

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

添加与非"匹配的可能性:

^([^"]*["][^"]*["][^"]*|[^"]?)*$

最后一步不允许任何内容匹配,也不允许使用任何字符。这允许匹配缺少"的字符串。请注意,需要使用行锚点,否则substring(s)将与此匹配。

Bonus:防止组反向引用(命名/编号组可能会使regexp引擎变慢一点):

^(?:[^"]*["][^"]*["][^"]*|[^"]?)*$

答案 4 :(得分:-1)

import re

def hasPairedQuotes(s):
    stripped = re.sub('[^"]', "", s)
    return len(stripped) % 2 == 0

>>> hasPairedQuotes("")
True
>>> hasPairedQuotes('""')
True
>>> hasPairedQuotes('"""')
False
>>> hasPairedQuotes('"Hello world!""')
False
>>> hasPairedQuotes('"Hello world!"')
True

很好,你想要一个正则表达式,这里是一个正则表达式:^[^"]*("[^"]*")*[^"]*$ ...但我认为可读性和可维护性的区别不言而喻。

>>> re.match(r'^[^"]*("[^"]*"[^"])*$', 'Hello ""')
<_sre.SRE_Match object at 0xb7cc0ce0>
>>> re.match(r'^[^"]*("[^"]*"[^"])*$', 'Hello "" "')
>>>