Perl正则可选捕获分组不工作,无法正确提取日志字段求助
问题原因
你写的正则无法捕获MsgType的核心问题是贪婪匹配的优先级问题:
- 正则中间的
.*是贪婪匹配规则,会优先尽可能多的匹配字符 - 你把
(MsgType=".*?")标记为了可选分组,正则引擎判断就算不匹配该分组也能满足整条正则的匹配规则,因此会直接让.*吞掉包括MsgType在内的所有后续内容,导致第二个捕获分组永远为空。
解决方法
提供两种可直接运行的实现方案:
方案1:分两次匹配字段,逻辑最直观,无匹配冲突问题
perl -ne '$sid = /(SessionID=".*?")/ ? $1 : ""; $mtype = /(MsgType=".*?")/ ? $1 : ""; print "$sid|$mtype\n"' sample.txt
分别对两个字段做独立匹配,没有匹配到就赋值为空字符串,完全规避了正则不同分组间的匹配冲突。
方案2:修改原有正则,将贪婪匹配改为非贪婪匹配
perl -ne '/(SessionID=".*?")?.*?(MsgType=".*?")?/ and print "$1|$2\n"' sample.txt
把原来的.*替换为非贪婪匹配.*?,正则引擎会尽可能少的匹配字符,优先检查后续的可选分组是否能匹配,不会吞掉MsgType的内容。
两种方案运行后都能得到你需要的输出:
SessionID="kkk"| SessionID="zkx"|MsgType="D"
内容的提问来源于stack exchange,提问作者Arthur Accioly
相关产品推荐
相关产品推荐

