我对这个正则表达式有问题。我想仅提取MATCH3
,因为其他人MATCH1
和MATCH2
已被注释掉。
# url(r'^MATCH1/$',),
#url(r'^MATCH2$',),
url(r'^MATCH3$',), # comment
正则表达式我捕获了所有的MATCH&#39。
(?<=url\(r'\^)(.*?)(?=\$',)
如何忽略以评论开头的行?负面前瞻?请注意,#
字符不一定在行的开头。
$'
后面的逗号。
答案 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']
另请注意,您不需要为您的模式起诉,您只需使用分组即可!