3

我正在尝试编写一个正则表达式来匹配可选引用的值(有效的引号是"'和`)。规则是两个引号的出现是一个转义的引号。

这是我想出的正则表达式:

(?P<quote>["'`])?(?P<value>(?(quote)((?!(?P=quote).)|((?=(?P=quote)).){2})*|[^\s;]*))(?(quote)(?P=quote)|)

现在可读(注释表明我认为它做了什么):

(?P<quote>["'`])?                   #named group Quote (any quoting character?)

    (?P<value>                      #name this group "value", what I am interested in
        (?(quote)               #if quoted 
            ((?!(?P=quote).)|((?=(?P=quote)).){2})* #see below
                                    #match either anything that is not the quote
                                    #or match 2 quotes
        |
            [^\s;]*         #match anything that is not whitespace or ; (my seperators if there are no quotes)
        )
    )

(?(quote)(?P=quote)|)               #if we had a leeding quote we need to consume a closing quote

它对不带引号的字符串执行良好,带引号的字符串会使其崩溃:

    match = re.match(regexValue, line)
  File "****/jython2.5.1/Lib/re.py", line 137, in match
    return _compile(pattern, flags).match(string)
RuntimeError: maximum recursion depth exceeded

我做错了什么?

编辑:示例输入 => 输出(用于捕获组“值”(所需)

text    => text
'text'  => text
te xt   => te
'te''xt'=> te''xt   #quote=' => strreplace("''","'") => desired result: te'xt
'te xt' => te xt

编辑2:在查看它时我注意到一个错误,见下文,但是我相信上面仍然是一个有效的 re +> 它可能是一个 Jython 错误,但它仍然没有做我想要它做的事情:(非常微妙差异,点移出前瞻组

new:(?P<quote>["'`])?(?P<value>(?(quote)((?!(?P=quote)).|((?=(?P=quote)).){2})*|[^\s;]*))(?(quote)(?P=quote)|)
old:(?P<quote>["'`])?(?P<value>(?(quote)((?!(?P=quote).)|((?=(?P=quote)).){2})*|[^\s;]*))(?(quote)(?P=quote)|)
4

3 回答 3

3

正如评论中所建议的,我建议明确并写下所有可能性:

r = r"""
    ([^"'`]+)
    |
    " ((?:""|[^"])*) "
    |
    ' ((?:''|[^'])*) '
    |
    ` ((?:``|[^`])*) `
"""

提取匹配项时,您可以使用仅填充一组四个的事实,并简单地删除所有空组:

r = re.compile(r, re.X)
for m in r.findall(''' "fo""o" and 'bar''baz' and `quu````x` '''):
    print ''.join(m)
于 2012-06-01T15:35:15.187 回答
0

经过一番折腾,我找到了解决方案:

good:(?P<quote>["'`])?(?P<value>(?(quote)((?!(?P=quote)).|((?=(?P=quote)).){2})*|[^;\s]*))(?(quote)(?P=quote)|)
bad :(?P<quote>["'`])?(?P<value>(?(quote)((?!(?P=quote)).|((?=(?P=quote)).){2})*|[^\s;]*))(?(quote)(?P=quote)|)

不,我不明白区别

于 2012-06-01T16:51:33.487 回答
0

如果我正确理解你的问题,给出一个包含 3 种不同类型引号的字符串

“你好,先生”,“猴子”说nonchalantly

您想要提取引用的值。在这种情况下,它们将是:

你好先生

漫不经心

以下表达式提取这些:

>>> expr = "\"(.*?)\"|'(.*?)'|`(.*?)`"

观察:

>>> s = """
"Hello, sir", said the 'monkey', `nonchalantly`. 
"""
>>> import re
>>> m = re.finditer(expr, s)
>>> for match in m:
...     print match.group()
...
('Hello, sir', None, None)
(None, 'monkey', None)
(None, None, 'nonchalantly')

顺便说一句,您自己的正则表达式似乎适用于我的 python 版本(Mac OSX 10.7.4 上的 cPython 2.7.2),但会产生错误的结果。

于 2012-06-01T15:42:19.107 回答