UNIX下如何编写正则表达式匹配首尾同序且中间含'm'的字符串并修正egrep命令问题
原正则匹配失效的核心问题
你当前的命令返回匹配数为0,是因为正则逻辑和实际需求存在完全错位,核心问题有三个:
- 反向引用顺序颠倒:原正则的捕获组逻辑要求字符串结构为「2位小写字母 → z开头的任意内容段 → 完全重复的z开头内容段 → 2位小写字母结尾」,和需求中“首尾序列相同、中间带m”的结构完全不匹配
- 指定字符写错:需求要求中间包含的指定字符是
m,原正则强制要求中间内容以z开头,完全没有匹配m的相关逻辑 - 中间规则错位:原正则要求中间内容必须被完整重复两次,属于完全多余的约束,和“中间任意位置带m即可”的需求冲突
适配需求的正确命令
按照你给出的校验规则(首尾为2位相同小写字母序列、中间任意位置包含m),对应的egrep计数命令为:
egrep -c '^([a-z]{2}).*m.*\1$' list
匹配逻辑拆解
^([a-z]{2}):从字符串起始位置捕获任意2位小写字母,作为需要匹配在字符串末尾的首尾序列(定义为捕获组1).*m.*:匹配捕获序列之后的所有中间内容,要求内容中任意位置至少出现一次m,m前后可以跟随任意数量的其他字符\1$:引用第一个捕获组的存储内容,要求字符串在结束前,必须和开头捕获的序列完全一致
校验示例的匹配效果
cahellomca:开头捕获ca,中间含m,结尾匹配ca→ 有效salomoresa:开头捕获sa,中间含m,结尾匹配sa→ 有效lonoletterlo:开头捕获lo,中间无m→ 无效homlastho:开头捕获ho,中间含m,结尾匹配ho→ 有效
最终匹配计数为3,和预期结果一致。
可选调整场景
- 如果场景中首尾序列不是固定2位长度,而是任意长度的相同字符序列,可以将捕获组调整为
^(.+).*m.*\1$,但这种写法会放开长度限制,可能匹配到不符合预期的1字符首尾场景,无特殊需求不建议随意调整 - 如果需要兼容大小写混合的字符串,可以给egrep增加
-i忽略大小写参数,命令为egrep -ic '^([a-z]{2}).*m.*\1$' list
内容的提问来源于stack exchange,提问作者stcol
相关产品推荐
相关产品推荐

