我正在尝试为我用Python编写的javascript预处理器添加一些轻量级降价支持。
在大多数情况下它正在工作,但有时我正在使用的正则表达式有点奇怪,我认为这与原始字符串和转义序列有关。
正则表达式是:(?<!\\)\"[^\"]+\"
是的,我知道它只匹配以"
字符开头的字符串。然而,这个项目出于好奇而不是任何事情,所以我现在可以忍受它。
要打破它:
(?<\\)\" # The group should begin with a quotation mark that is not escaped
[^\"]+ # and match any number of at least one character that is not a quotation mark (this is the biggest problem, I know)
\" # and end at the first quotation mark it finds
话虽这么说,我(显然)开始遇到类似这样的问题:
"This is a string with an \"escaped quote\" inside it"
我不确定如何说“除了引号外的所有内容,除非该标记被转义”。我试过了:
([^\"]|\\\")+ # a group of anything but a quote or an escaped quote
,但这会导致非常奇怪的结果。
我完全准备好听到我说这一切都错了。为简单起见,假设这个正则表达式总是以双引号("
)开头和结尾,以避免在混合中添加另一个元素。我真的很想了解到目前为止的情况。
感谢您的帮助。
修改
作为正则表达式的测试,我试图使用以下代码在缩小的jQuery脚本中找到所有字符串文字(使用下面的unutbu模式):
STRLIT = r'''(?x) # verbose mode
(?<!\\) # not preceded by a backslash
" # a literal double-quote
.*? # non-greedy 1-or-more characters
(?<!\\) # not preceded by a backslash
" # a literal double-quote
'''
f = open("jquery.min.js","r")
jq = f.read()
f.close()
literals = re.findall(STRLIT,jq)
以下答案解决了几乎所有问题。确实出现的是jquery自己的正则表达式,这是一个非常优秀的案例。该解决方案不再错误地将有效的javascript标识为markdown链接,这确实是目标。
答案 0 :(得分:6)
我想我第一次看到这个想法...... Jinja2的源代码?后来将其移植到Mako。
r'''(\"\"\"|\'\'\'|\"|\')((?<!\\)\\\1|.)*?\1'''
以下是:
(\"\"\"|\'\'\'|\"|\')
匹配Python开头引用,因为这恰好是从用于解析Python的代码中获取的。您可能不需要所有这些报价类型。((?<!\\)\\\1|.)
匹配:只有一个匹配的引用,它只被转义为ONCE或任何其他字符。因此,\\"
仍将被识别为字符串的结尾。*?
非贪婪地匹配尽可能多的人。\1
只是收尾报价。唉,\\\"
仍然会被错误地检测为字符串的结尾。 (模板引擎只使用它来检查是否一个字符串,而不是提取它。)这是一个非常适合正则表达式的问题;如果没有在Perl中做疯狂的事情,你可以将真正的代码嵌入到正则表达式中,我不确定即使使用PCRE也是如此。虽然我喜欢被证明是错的。 :)杀手是(?<!...)
必须是恒定长度,但是你想在结束引号之前检查是否有任何甚至数量的反斜杠。 / p>
如果你想要正确,而不仅仅是大多数正确,你可能必须使用真正的解析器。请查看parsley,pyparsing或any of these tools。
编辑:顺便说一句,没有必要检查开头引号之前没有反斜杠。这不是JS(或Python)中字符串之外的有效语法。
答案 1 :(得分:3)
也许使用两个负面的背后:
import re
text = r'''"This is a string with an \"escaped quote\" inside it". While ""===r?+r:wt.test(r)?st.parseJSON(r) :r}catch(o){}st.data(e,n,r)}else r=t}return r}function s(e){var t;for(t in e)if(("data" '''
for match in (re.findall(r'''(?x) # verbose mode
(?<!\\) # not preceded by a backslash
" # a literal double-quote
.*? # 1-or-more characters
(?<!\\) # not preceded by a backslash
" # a literal double-quote
''', text)):
print(match)
产量
"This is a string with an \"escaped quote\" inside it"
""
"data"
.+?
中的问号使得模式不贪婪。非贪婪导致模式在遇到第一个未转义的双引号时匹配。
答案 2 :(得分:0)
使用python,正确的正则表达式匹配双引号字符串是:
pattern = r'“(\。| [^”])*“'
它描述了字符串的开头和结尾“。对于两个双引号内的每个字符,它可以是转义字符,也可以是任何字符”。
unutbu的ansever是错误的,因为对于有效的字符串“\\\\”,无法与该模式匹配。