使用sed提取字符串中数字+M重复模式失败,哪里操作有误?
问题原因
- 正则贪婪匹配特性导致捕获结果不符合预期:你写的
.*\([0-9]*M\).*中,开头的.*会尽可能多地匹配字符,而[0-9]*允许匹配0个数字,所以.*会一直匹配到最后一个M的前一位,最终捕获组\1只能拿到单独的M。就算把[0-9]*改成[0-9]\+避免0匹配,最终也只能拿到最后一个符合规则的19M,无法同时获取两个M相关的片段。 - 写法逻辑不匹配需求:“匹配整行替换为单个捕获组内容”的逻辑只能提取单个片段,没法同时提取多个符合规则的片段。你之前执行
sed 's/\([0-9]*M\)//g'能成功删除所有对应内容,是因为g参数会全局替换所有匹配到的片段,反过来要保留这些片段,不能用整行匹配的写法,要改成删除所有不符合规则的内容。
正确实现方法
方法1:用grep实现(更简单直观,推荐)
用grep -o输出每个匹配到的片段,再用tr删除换行拼接结果:
echo "23S62M1I19M2D" | grep -Eo '[0-9]+M' | tr -d '\n'
输出结果就是你期望的62M19M。
方法2:用GNU sed实现
用全局替换逻辑删除所有不符合[0-9]+M规则的字符:
echo "23S62M1I19M2D" | sed -E 's/([0-9]+M)|./\1/g'
该写法的逻辑是:匹配到[0-9]+M就保留,匹配到其他任意字符就替换为空,全局替换后就只剩下所有符合规则的片段。
内容的提问来源于stack exchange,提问作者aerijman
相关产品推荐
相关产品推荐

