正则表达式解析日志比split快5倍——Python文本处理
先说结论
大数据文本处理核心正则技巧:① 命名分组(?P
先把这段讲顺;面试官追问时,再展开下面的原理和细节。
详细讲解
正则基础
import re
# 命名分组提取Nginx日志
LOG_RE = re.compile(
r'(?P<ip>\S+) \S+ \S+ '
r'\[(?P<time>[^\]]+)\] '
r'"(?P<method>\w+) (?P<path>\S+) \S+" '
r'(?P<status>\d+) (?P<size>\d+)')
match = LOG_RE.match(log_line)
if match: data = match.groupdict()
# {'ip':'192.168.1.1','status':'200',...}
compile预编译性能
# 不预编译:100万行约1.5秒
for line in lines: re.match(r'\d{4}-\d{2}-\d{2}', line)
# 预编译:100万行约0.8秒(快一倍)
pat = re.compile(r'\d{4}-\d{2}-\d{2}')
for line in lines: pat.match(line)
贪婪vs非贪婪
text = '<div>hello</div><div>world</div>'
re.findall(r'<div>(.*)</div>', text) # ['hello</div><div>world'] 贪婪
re.findall(r'<div>(.*?)</div>', text) # ['hello','world'] 非贪婪
Pandas内置正则
df['date'] = df['log'].str.extract(r'(\d{4}-\d{2}-\d{2})')
errors = df[df['msg'].str.contains(r'ERROR|FATAL', na=False)]
df['phone'] = df['phone'].str.replace(r'(\d{3})\d{4}(\d{4})',r'\1****\2')
实战:日志解析split vs 正则
100万行Nginx日志:split方式2.5秒且格式异常崩溃;正则方式0.5秒(快5倍)且异常返回None不崩。
面试高频追问
追问一:正则灾难性回溯?
嵌套量词.*.*可能指数级回溯。用非贪婪.*?或精确字符类[^"]*替代。
追问二:match和search区别?
match从开头匹配,search在整个字符串搜索。大部分场景用search更灵活。
追问三:什么时候不该用正则?
简单split能搞定时不用。解析JSON/XML/HTML用json.loads()/lxml。正则适合半结构化文本。
总结
正则讲三层:① 核心语法(命名分组、贪婪vs非贪婪);② 性能优化(compile预编译);③ 大数据应用(日志解析比split快5倍、Pandas str.extract/contains内置正则)。
下一篇聊Python异常处理:try-except写得太粗的危害。
你们用正则做什么文本处理?评论区聊聊~
关注「Wood聊大数据」| 9年大数据老兵,只讲大数据面试干货