sed反向引用异常问题:多匹配项仅返回最后结果的原因及解决方法咨询
异常现象成因
- 核心原因是POSIX正则默认采用贪婪匹配规则:你原始正则中的
.*会尽可能匹配最长的符合要求的字符串。当一行存在多个结构时,!\[.*\]中的.*会从第一个[一直匹配到整行最后一个],导致整个正则最终只能捕获到行末最后一个图片结构,因此输出结果永远指向最后一个匹配项。
实现预期需求的方案
需求1:仅输出首个匹配项的处理结果
将正则中的贪婪匹配替换为边界限定匹配,匹配到首个结果后直接输出并终止处理即可,命令如下:
sed -n 's@| !\[[^]]*\](\(\/img\/\)\([0-9]*\/[0-9]*\/[0-9]*\)\.\([^.]*\)\.\([^)]*\)) |@|  |@p;q'
说明:用[^]]*替代.*匹配[]内的内容,会在遇到第一个]时停止匹配,避免吞掉后续内容;末尾追加q命令,首次匹配替换完成后直接退出sed进程,仅输出首个匹配的处理结果。
需求2:处理所有匹配项后输出完整行
同样先替换贪婪匹配为边界限定匹配,再给替换命令追加全局标记g,让sed对一行内所有符合规则的匹配项依次执行替换:
sed -n 's@| !\[[^]]*\](\(\/img\/\)\([0-9]*\/[0-9]*\/[0-9]*\)\.\([^.]*\)\.\([^)]*\)) |@|  |@gp'
说明:g标记会让sed扫描整行所有非重叠的匹配项,逐个完成替换后再输出完整修改后的行,即可得到所有图片alt都填充完成的结果。
内容的提问来源于stack exchange,提问作者Mikhail Morfikov
相关产品推荐
相关产品推荐

