Python正则如何正确提取日志中SEARCH |后的完整搜索内容
问题背景
现有固定格式的业务日志,需要提取每行中SEARCH |标识后的完整搜索词(支持包含空格的多词内容),并完成词频统计。
示例日志内容:
2022-06-29 12:45:04.652 | INFO | product.views.product_view:list:28 - SEARCH | Humana papa 2022-06-29 12:45:04.652 | INFO | product.views.product_view:list:28 - SEARCH | iPhone 12
预期提取结果为Humana papa、iPhone 12这类完整搜索字符串。
原有实现代码使用正则r'SEARCH \| (\w+).*'做匹配,存在明显缺陷:\w+仅能匹配连续的字母、数字、下划线字符,遇到空格就会终止匹配,只能拿到搜索词的第一个单词,最终词频统计结果完全错误。例如测试输入中的Phone 12 pro会被错误截断为Phone,末尾带空格的Humana papa 会被截断为Humana,最终得到Humana出现2次的错误统计结果。
修正方案
核心是调整正则匹配规则,直接捕获SEARCH |之后到当前行末尾的所有内容,同时自动过滤内容前后的多余空白字符,无需额外做字符串截断处理。
修正后完整代码
import re from collections import Counter inp = """2022-06-29 12:45:04.652 | INFO | product.views.product_view:list:28 - SEARCH | Humana 2022-06-29 12:45:04.652 | INFO | product.views.product_view:list:28 - SEARCH | Car 2022-06-29 12:45:04.652 | INFO | product.views.product_view:list:28 - SEARCH | Phone 12 pro 2022-06-29 12:45:04.652 | INFO | product.views.product_view:list:28 - SEARCH | Humana papa """ # 正则说明: # 1. SEARCH \| 匹配固定标记,管道符需要转义 # 2. \s* 吞掉标记后可能存在的多余空白 # 3. (.*?) 非贪婪捕获搜索词内容 # 4. \s*$ 匹配搜索词末尾到行尾的空白,配合re.MULTILINE逐行匹配 terms = re.findall(r'SEARCH \|\s*(.*?)\s*$', inp, flags=re.MULTILINE) print(Counter(terms)) # 输出:Counter({'Humana': 1, 'Car': 1, 'Phone 12 pro': 1, 'Humana papa': 1}) print(Counter(terms).most_common(1)[0]) # 输出:('Humana', 1)
注意事项
- 必须添加
re.MULTILINE标志,否则正则中的$只会匹配整个输入字符串的末尾,无法逐行提取内容 - 正则前后的
\s*已经自动处理了搜索词首尾的空格、换行、制表符,不需要额外调用strip()方法 - 如果日志格式固定为
SEARCH |后到行尾无其他内容,也可以将非贪婪匹配.*?替换为贪婪匹配.*,匹配结果完全一致
内容的提问来源于stack exchange,提问作者CaptainPy
相关产品推荐
相关产品推荐

