正则表达式‘标志未在表达式开头’弃用警告困惑求解
问题原因及解决方法
你遇到的警告确实是字符串拼接导致的。问题出在white_space变量里的(?ms)内联修饰符——当你把它拼接到其他正则表达式的末尾时,这个修饰符就跑到了整个正则表达式的中间/结尾位置,而Python 3.11及以上版本要求内联修饰符必须放在正则的最开头,否则会触发弃用警告。
具体解决思路
有两种可行的修复方式:
方式一:改用re.compile的flags参数替代内联修饰符
把white_space里的(?ms)去掉,然后在编译每个正则时统一传入对应的标志位:
import re # 移除内联修饰符(?ms) white_space = r'(\s*(\{[^\n]*?\})?\s*)' # 编译时通过flags传入MULTILINE(m)和DOTALL(s) import_re = re.compile( r'^\s*import\s+"(?P<filename>.+?)"(\s+as\s(?P<asname>[a-zA-Z_][a-zA-Z0-9_.]*))?%s$' % white_space, flags=re.MULTILINE | re.DOTALL ) param = white_space + r'([$%@!?~]?[\w\.]+|#[\w\.]+#)' + white_space params = r'%s(,%s)*' % (param, param) m = re.compile( r'^\s*macro\s+(?P<name>[a-zA-Z0-9_]+(\.[a-zA-Z_0-9.]+)*)\s*(?P<params>\(%s\))?' % params, flags=re.MULTILINE | re.DOTALL ) macro_call_re = re.compile( r'^\s*([\w_.]+)\s*(\(.*\))?%s$' % white_space, flags=re.MULTILINE | re.DOTALL )
方式二:确保内联修饰符在整个正则的最开头
如果一定要保留内联修饰符的写法,就把(?ms)放在每个编译正则的字符串最开头,而不是藏在white_space里:
import re white_space = r'(\s*(\{[^\n]*?\})?\s*)' # 把(?ms)移到正则字符串的最开头 import_re = re.compile(r'(?ms)^s*import\s+"(?P<filename>.+?)"(\s+as\s(?P<asname>[a-zA-Z_][a-zA-Z0-9_.]*))?%s$' % white_space) param = white_space + r'([$%@!?~]?[\w\.]+|#[\w\.]+#)' + white_space params = r'%s(,%s)*' % (param, param) m = re.compile(r'(?ms)^\s*macro\s+(?P<name>[a-zA-Z0-9_]+(\.[a-zA-Z_0-9.]+)*)\s*(?P<params>\(%s\))?' % params) macro_call_re = re.compile(r'(?ms)^\s*([\w_.]+)\s*(\(.*\))?%s$' % white_space)
两种方式都能解决警告问题,推荐第一种——用flags参数更清晰,也避免了拼接导致的修饰符位置混乱。
内容的提问来源于stack exchange,提问作者Mario Krušelj
相关产品推荐
相关产品推荐

