正则表达式否定前瞻忽略评论

时间:2015-02-16 18:54:07

标签: python regex negative-lookahead

我对这个正则表达式有问题。我想仅提取MATCH3,因为其他人MATCH1MATCH2已被注释掉。

#   url(r'^MATCH1/$',),
   #url(r'^MATCH2$',),
    url(r'^MATCH3$',), # comment

正则表达式我捕获了所有的MATCH&#39。

(?<=url\(r'\^)(.*?)(?=\$',)

如何忽略以评论开头的行?负面前瞻?请注意,#字符不一定在行的开头。

编辑:抱歉,所有答案都很好!该示例忘记了匹配组末尾$'后面的逗号。

4 个答案:

答案 0 :(得分:1)

^\s*#.*$|(?<=url\(r'\^)(.*?)(?=\$'\))

试试这个。抓住捕获。参见演示。

https://www.regex101.com/r/rK5lU1/37

import re
p = re.compile(r'^\s*#.*$|(?<=url\(r\'\^)(.*?)(?=\$\'\))', re.IGNORECASE | re.MULTILINE)
test_str = "# url(r'^MATCH1/$'),\n #url(r'^MATCH2$'),\n url(r'^MATCH3$') # comment"

re.findall(p, test_str)

答案 1 :(得分:1)

如果这是您需要匹配的唯一位置,则匹配行的开头,后跟可选的空格,后跟url

(?m)^\s*url\(r'(.*?)'\)

如果您需要涵盖更复杂的案例,我建议使用ast.parse,因为它真正了解Python源代码解析规则。

import ast

tree = ast.parse("""(
#   url(r'^MATCH1/$'),
   #url(r'^MATCH2$'),
    url(r'^MATCH3$') # comment
)""")

class UrlCallVisitor(ast.NodeVisitor):
    def visit_Call(self, node):
        if getattr(node.func, 'id', None) == 'url':
            if node.args and isinstance(node.args[0], ast.Str):
                print(node.args[0].s.strip('$^'))

        self.generic_visit(node)

UrlCallVisitor().visit(tree)

打印给名为url的函数的每个第一个字符串文字参数;在这种情况下,它会打印MATCH3。请注意,ast.parse的源代码必须是格式良好的Python源代码(因此括号,否则会引发SyntaxError。)

答案 2 :(得分:1)

你真的不需要在这里使用外观,你可以寻找可能的领先空白,然后匹配&#34; url&#34;和前面的背景;捕捉你想要保留的部分。

>>> import re
>>> s = """#   url(r'^MATCH1/$',),
   #url(r'^MATCH2$',),
    url(r'^MATCH3$',), # comment"""
>>> re.findall(r"(?m)^\s*url\(r'\^([^$]+)", s)
['MATCH3']

答案 3 :(得分:1)

作为替代方案,您可以使用&#39;#&#39;如果第一个元素有&#39; url&#39; in(它不以#开头)你可以使用re.search来匹配你想要的子字符串:

>>> [re.search(r"url\(r'\^(.*?)\$'" ,i[0]).group(1) for i in [line.split('#') for line in s.split('\n')] if 'url' in i[0]]
['MATCH3']

另请注意,您不需要为您的模式起诉,您只需使用分组即可!