我正在尝试为我用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
Run Code Online (Sandbox Code Playgroud)
话虽如此,我(显然)开始遇到这样的问题:
"This is a string with an \"escaped quote\" inside it"
我不太确定如何说"除了引号之外的所有内容,除非该标记被转义".我试过了:
([^\"]|\\\")+ # a group of anything but a quote or an escaped quote
Run Code Online (Sandbox Code Playgroud)
,但这会导致非常奇怪的结果.
我完全准备好听到我说这一切都错了.为简单起见,假设这个正则表达式总是以双引号(")开头和结尾,以避免在混合中添加另一个元素.我真的很想了解到目前为止的情况.
谢谢你的帮助.
编辑
作为正则表达式的测试,我试图使用以下代码在缩小的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)
Run Code Online (Sandbox Code Playgroud)
以下答案几乎解决了所有问题.确实出现的是jquery自己的正则表达式,这是一个非常优秀的案例.该解决方案不再错误地将有效的javascript标识为markdown链接,这确实是目标.
我想我第一次看到这个想法...... Jinja2的源代码?后来将其移植到Mako.
r'''(\"\"\"|\'\'\'|\"|\')((?<!\\)\\\1|.)*?\1'''
Run Code Online (Sandbox Code Playgroud)
具体如下:
(\"\"\"|\'\'\'|\"|\')匹配Python开头引用,因为这恰好来自解析Python的代码.您可能不需要所有这些报价类型.((?<!\\)\\\1|.)匹配:只有一个匹配的引用,它只被转义为ONCE或任何其他字符.所以\\"仍然会被认为是字符串的结尾.*? 非贪婪地尽可能多地匹配.\1只是收尾报价.唉,\\\"仍然会被错误地检测为字符串的结尾.(模板引擎只用它来检查是否有是一个字符串,而不是将其解压.)这是一个问题的正则表达式非常非常不适合; 如果没有在Perl中做疯狂的事情,你可以将真正的代码嵌入到正则表达式中,我不确定即使使用PCRE也是如此.虽然我喜欢被证明是错的.:)杀手(?<!...)必须是恒定长度,但你想检查在结束报价之前是否有任何偶数个反斜杠.
如果你想要正确,而不仅仅是大多数正确,你可能必须使用真正的解析器.看看欧芹,pyparsing或任何这些工具.
编辑:顺便说一下,没有必要检查开头的引号在它之前没有反斜杠.这不是JS(或Python)中字符串之外的有效语法.
也许使用两个负面的看法:
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)
Run Code Online (Sandbox Code Playgroud)
产量
"This is a string with an \"escaped quote\" inside it"
""
"data"
Run Code Online (Sandbox Code Playgroud)
中的问号.+?使模式非贪婪。非贪婪导致模式在遇到第一个未转义的双引号时匹配。
| 归档时间: |
|
| 查看次数: |
3155 次 |
| 最近记录: |