使用全局标志进行Python正则表达式编译
有没有办法定义一个全局标志,让Python的re.compile()
自动设置这个标志呢?比如说,我想在一个类里,所有的正则表达式都使用re.DOTALL
这个标志。
这听起来可能有点奇怪,但我其实无法控制这部分代码,因为它是由YAPPS生成的。我只是给YAPPS提供一个包含正则表达式的字符串,然后它会调用re.compile()
。可惜的是,我需要在re.DOTALL
模式下使用它。
一个快速的解决办法是编辑生成的解析器,添加合适的选项。但我还是希望能有其他更自动化的方法来实现这个。
补充说明:Python允许你使用(?...)的结构来设置标志,所以在我的情况下,re.DOTALL
可以用(?s)来表示。虽然这样很有用,但它并不能应用于整个类或者整个文件。
所以我的问题依然存在。
2 个回答
8
所有的标志都可以直接在正则表达式里设置:
r"(?s)Your.*regex.*here"
12
是的,你可以把它设置为全局的 re.DOTALL
。但是你不应该这样做。全局设置在任何时候都是个坏主意——这可能会导致同一个Python实例运行的其他代码出错。
所以,不要这样做:
你可以利用Python解释器每个实例都会缓存模块的特点,这样如果其他人导入同一个模块,他们也会得到你可以访问的那个对象。所以你可以把 re.compile
重新绑定到一个代理函数,这个函数会传递 re.DOTALL
。
import re
re.my_compile = re.compile
re.compile = lambda pattern, flags: re.my_compile(pattern, flags | re.DOTALL)
这样一来,所有其他人也会受到这个改变的影响。
你甚至可以把这个封装在一个上下文管理器里,像这样:
from contextlib import contextmanager
@contextmanager
def flag_regexen(flag):
import re
re.my_compile = re.compile
re.compile = lambda pattern, flags: re.my_compile(pattern, flags | flag)
yield
re.compile = re.my_compile
然后
with flag_regexen(re.DOTALL):
<do stuff with all regexes DOTALLed>