Python Regex否定前瞻忽略注释
这个正则表达式有问题。我只想退出Python Regex否定前瞻忽略注释,python,regex,negative-lookahead,Python,Regex,Negative Lookahead,这个正则表达式有问题。我只想退出MATCH3,因为其他的MATCH1和MATCH2都被注释掉了 # url(r'^MATCH1/$',), #url(r'^MATCH2$',), url(r'^MATCH3$',), # comment 我拥有的正则表达式捕获了所有的匹配项 (?<=url\(r'\^)(.*?)(?=\$',) (?^\s*#.*$|)(?^\s*#.*$|)(?如果这是唯一需要匹配的地方,则匹配行的开头,后跟可选空格,后跟url: (?m)^\s*
MATCH3
,因为其他的MATCH1
和MATCH2
都被注释掉了
# url(r'^MATCH1/$',),
#url(r'^MATCH2$',),
url(r'^MATCH3$',), # comment
我拥有的正则表达式捕获了所有的匹配项
(?<=url\(r'\^)(.*?)(?=\$',)
(?^\s*#.*$|)(?^\s*#.*$|)(?如果这是唯一需要匹配的地方,则匹配行的开头,后跟可选空格,后跟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
).如果这是唯一需要匹配的地方,则匹配行的开头,后跟可选空格,后跟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
).您确实不需要在此处使用lookarounds,您可以查找可能的前导空格,然后匹配“url”和前面的上下文;捕获您想要保留的部分
>>> import re
>>> s = """# url(r'^MATCH1/$',),
#url(r'^MATCH2$',),
url(r'^MATCH3$',), # comment"""
>>> re.findall(r"(?m)^\s*url\(r'\^([^$]+)", s)
['MATCH3']
您确实不需要在这里使用lookarounds,您可以查找可能的前导空格,然后匹配“url”和前面的上下文;捕获您想要保留的部分
>>> import re
>>> s = """# url(r'^MATCH1/$',),
#url(r'^MATCH2$',),
url(r'^MATCH3$',), # comment"""
>>> re.findall(r"(?m)^\s*url\(r'\^([^$]+)", s)
['MATCH3']
或者,如果第一个元素中有“url”(不以#开头),则可以使用“#”拆分行。您可以使用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']
另外请注意,您不需要四处寻找您的模式,您可以使用分组!作为替代方法,您可以使用“#”分割行,如果第一个元素中有“url”(它不是以#开头),您可以使用重新搜索
来匹配您想要的子字符串:
>>> [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']
还要注意的是,你不需要四处寻找你的模式,你可以使用分组