Python3.8.16下re.error: bad escape \s,日志异常检测模型迁移问题
Python2迁移Python3后re.sub报错解决方案
问题描述
日志异常检测模型在Python2环境运行正常,迁移到Python3后触发re.error: bad escape \s at position 0错误,报错代码行:
splitter = re.sub(' +', '\s+', splitters[k])
已尝试替换import re为import regex as re,并将替换字符串改为\\\s+,但问题未解决。
完整报错回溯
File "AEL_demo.py", line 16, in <module> parser.parse(log_file) File "/media/cvpr/CM_24/logparser/demo/../logparser/AEL/AEL.py", line 47, in parse self.load_data() File "/media/cvpr/CM_24/logparser/demo/../logparser/AEL/AEL.py", line 180, in load_data headers, regex = self.generate_logformat_regex(self.logformat) File "/media/cvpr/CM_24/logparser/demo/../logparser/AEL/AEL.py", line 213, in generate_logformat_regex splitter = re.sub(' +', '\s+', splitters[k]) File "/home/cvpr/anaconda3/envs/logpare/lib/python3.8/re.py", line 210, in sub return _compile(pattern, flags).sub(repl, string, count) File "/home/cvpr/anaconda3/envs/logpare/lib/python3.8/re.py", line 327, in _subx template = _compile_repl(template, pattern) File "/home/cvpr/anaconda3/envs/logpare/lib/python3.8/re.py", line 318, in _compile_repl return sre_parse.parse_template(repl, pattern) File "/home/cvpr/anaconda3/envs/logpare/lib/python3.8/sre_parse.py", line 1042, in parse_template raise s.error('bad escape %s' % this, len(this)) re.error: bad escape \s at position 0
原代码片段
for k in range(len(splitters)): if k % 2 == 0: splitter = re.sub(' +', '\s+', splitters[k]) regex += splitter else: header = splitters[k].strip('<').strip('>') regex += '(?P<%s>.*?)' % header headers.append(header) regex = re.compile('^' + regex + '$') return headers, regex
解决方案
问题根源是Python3的re.sub对替换字符串的转义规则比Python2更严格:Python2会忽略替换字符串中未定义的转义序列(直接保留原字符),但Python3会直接抛出错误。
只需将替换字符串改为原始字符串或正确转义反斜杠即可:
方法1:使用原始字符串(推荐)
将报错行修改为:
splitter = re.sub(' +', r'\s+', splitters[k])
原始字符串前缀r会让Python不解析字符串内的转义序列,直接将\s+作为普通字符串传递给re.sub。
方法2:双反斜杠转义
如果不想用原始字符串,也可以用双反斜杠转义\:
splitter = re.sub(' +', '\\s+', splitters[k])
此时Python会将\\解析为单个\,传递给re.sub的就是\s+。
方法3:若坚持使用regex库
如果继续用regex库,需确保替换字符串的转义正确,同样可以用原始字符串:
import regex as re # ... splitter = re.sub(' +', r'\s+', splitters[k])
修改后完整代码片段
for k in range(len(splitters)): if k % 2 == 0: splitter = re.sub(' +', r'\s+', splitters[k]) regex += splitter else: header = splitters[k].strip('<').strip('>') regex += '(?P<%s>.*?)' % header headers.append(header) regex = re.compile('^' + regex + '$') return headers, regex
内容的提问来源于stack exchange,提问作者Khawar Islam
相关产品推荐
相关产品推荐

