我想解析一个输入字符串,并确定它是否包含由双引号 (
为了使事情更加复杂,反斜杠本身可以被转义,如下所示:
我正在尝试使用 Python 的
在扫描目标字符串时,从左到右尝试使用由
然而,这并不像我预期的那样工作:
这个正则表达式的想法是首先检查转义字符(
我希望字符串
我真的不知道回溯在这种情况下如何工作,但是否有一种避免它的方法?
我猜如果我首先在单独的步骤中检查初始的
"
) 包围的字符序列。该字符序列本身不允许包含进一步的双引号,除非它们被反斜杠转义,如下所示: \"
。为了使事情更加复杂,反斜杠本身可以被转义,如下所示:
\\
。因此,由两个(或任何偶数个)反斜杠 (\\")
前缀的双引号不会被转义。更糟糕的是,允许单个非转义反斜杠 (即后面既不跟 "
也不跟 \\
的反斜杠)。我正在尝试使用 Python 的
re
模块来解决这个问题。 模块文档 告诉我们有一个管道运算符 A|B
:在扫描目标字符串时,从左到右尝试使用由
'|'
分隔的正则表达式。当一个模式完全匹配时,该分支将被接受。这意味着一旦A
匹配成功,即使它可以产生更长的整体匹配,B
也不会进一步测试。换句话说,'|'
运算符从不贪婪。然而,这并不像我预期的那样工作:
>>> import re
>>> re.match(r'"(\\[\\"]|[^"])*"', r'"a\"')
<_sre.SRE_Match object; span=(0, 4), match='"a\\"'>
这个正则表达式的想法是首先检查转义字符(
\\
或\"
),只有在找不到它时,才检查任何不是"
的字符(但它可以是单个\
)。这可能会发生任意次数,并且必须用字面上的"
字符括起来。我希望字符串
"a\"
根本不匹配,但显然它确实匹配了。我希望\"
匹配A
部分,而B
部分不被测试,但显然它确实被测试了。我真的不知道回溯在这种情况下如何工作,但是否有一种避免它的方法?
我猜如果我首先在单独的步骤中检查初始的
"
字符(并从输入中删除它),那么它将起作用。然后,我可以使用以下正则表达式获取字符串的内容:>>> re.match(r'(\\[\\"]|[^"])*', r'a\"')
<_sre.SRE_Match object; span=(0, 3), match='a\\"'>
这将包括转义引号。由于不会剩下一个闭合引号,我会知道总体上给定的字符串不匹配。
我必须这样做吗?还是可能用单个正则表达式解决这个问题,而不需要额外的手动检查?
在我的实际应用中,“”括起来的字符串只是更大模式的一部分,因此我认为在单个正则表达式中一次完成所有操作会更简单。
我找到了类似的问题,但是它们没有考虑到单个非转义反斜杠可以是字符串的一部分:使用正则表达式解析带有转义字符的字符串, 使用正则表达式解析转义字符。
"(?:[^\\"]|\\.)*"
-->"[^"\\]*(?:\\.[^"\\]*)*"
- Wiktor Stribiżew