【发布时间】:2009-04-04 06:09:02
【问题描述】:
我想出了:([^"]*["][^"]*["][^"]*)*
它适用于所有情况,除了空字符串。我认为它会起作用,因为最后一颗星与前一个标记匹配 零 次或更多次。
有什么想法吗?
另外,如果有更好的方法,请告诉我并详细解释。
解决方案必须是正则表达式,因为使用它的地方是一个需要正则表达式的钩子。
它也必须匹配不带引号的字符串,因为零是偶数
【问题讨论】:
标签: regex
我想出了:([^"]*["][^"]*["][^"]*)*
它适用于所有情况,除了空字符串。我认为它会起作用,因为最后一颗星与前一个标记匹配 零 次或更多次。
有什么想法吗?
另外,如果有更好的方法,请告诉我并详细解释。
解决方案必须是正则表达式,因为使用它的地方是一个需要正则表达式的钩子。
它也必须匹配不带引号的字符串,因为零是偶数
【问题讨论】:
标签: regex
试试这个表达式:
^(?:[^"]+|"[^"]*")*$
它匹配一个序列,该序列由除引号以外的任何字符 ([^"]+) 或一对带有除引号以外的任何字符的引号 ("[^"]*") 组成。 * 量词将空字符串考虑在内。
【讨论】:
您的正则表达式 应该 匹配完全空的字符串,但不匹配例如一个由单个空格组成的字符串,因为您的正则表达式指出如果字符串不是完全为空,则它需要包含至少一个双引号。这是因为正则表达式中的 ["] 标记后面没有 *.
考虑所需正则表达式的正确方法如下:您要匹配(不带双引号的字符串)后跟(双引号)加上(不带双引号的字符串)后跟(双)引号后跟(字符串不带双引号),然后从第一个 'followed by' 开始无限重复。没有双引号的字符串是 [^"]*,所以你得到(为了可读性添加了空格):
[^"]* (" [^"]* " [^"]*)*
如果您将此与您的正则表达式进行比较,则第一个 [^"]* 已被移出 重复。
【讨论】:
似乎正则表达式不是适合这项工作的工具。编辑:但是,您似乎仅限于此。鉴于该限制,这并不能回答您的问题,但没有它也能很好地工作。
只需遍历您的字符串并计数。 C 示例:
bool hasEvenNumberOfQuotes(const char *str)
{
bool even = true;
while(*str != '\0')
{
if(*str == '"')
even = !even;
++str;
}
return even;
}
【讨论】:
根据您的正则表达式:
([^"]*["][^"]*["][^"]*)*
添加线锚:
^([^"]*["][^"]*["][^"]*)*$
增加匹配非"的可能性:
^([^"]*["][^"]*["][^"]*|[^"]?)*$
这最后一步不允许匹配任何内容或消耗一个字符。这允许匹配缺少" 的字符串。请注意,需要行锚,否则子字符串将与此匹配。
奖励:防止组反向引用(命名/编号组可能会稍微减慢正则表达式引擎):
^(?:[^"]*["][^"]*["][^"]*|[^"]?)*$
【讨论】:
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 "" "')
>>>
【讨论】: