sed中正则表达式匹配失效,求电话号码分段提取的正确方法
如何用sed格式化电话号码输出?
我有一个名为dbbackup的文件,内容如下:
[root@ip-12-32-8-15 ~]# cat dbbackup (555)555-1212 (555)555-1213
我期望把每一行的电话号码拆分成指定格式,输出结果如下:
First: (555) Second: 555- Third: 1212 First: (555) Second: 555- Third: 1213
我尝试用下面的sed命令处理,但没有生效:
sed -n -e 's/\([0-9]+)\)\([0-9]+-\)\([0-9]+\)/First: \1 Second: \2 Third: \3/p' dbbackup
问题分析
你的sed命令有两个关键问题:
- 正则语法错误:第一个捕获组的右括号没有转义(写成了
)\),正确应该是\)),导致正则表达式无法正确解析。 - 量词不生效:在sed默认的**基础正则表达式(BRE)**模式下,
+是字面字符,不是表示"一个或多个"的量词,所以[0-9]+无法匹配连续数字。
解决方案
你可以选择两种方式来实现需求:
方式1:使用扩展正则表达式(ERE)推荐
使用-E参数(GNU sed和macOS sed都支持,部分旧系统用-r)启用扩展正则,这样正则写法更直观,不需要转义括号和+:
sed -nE 's/(\([0-9]+\))([0-9]+-)([0-9]+)/First: \1 Second: \2 Third: \3/p' dbbackup
这个正则的分组逻辑:
(\([0-9]+\)):捕获第一组,匹配完整的(555)部分(\(和\)是字面括号,[0-9]+匹配连续数字)([0-9]+-):捕获第二组,匹配555-部分([0-9]+):捕获第三组,匹配最后的1212部分
方式2:使用基础正则表达式(BRE)
如果不想用扩展正则,需要修正语法,把+转义为\+,同时修正括号的转义:
sed -n 's/\(\([0-9]\+\)\)\([0-9]\+-\)\([0-9]\+\)/First: \1 Second: \3 Third: \4/p' dbbackup
这里的分组逻辑是:
\(\([0-9]\+\)\):捕获第一组,包含完整的(555)(\(和\)是字面括号,\([0-9]\+\)捕获中间的数字)\([0-9]\+-\):捕获第三组,匹配555-\([0-9]\+\):捕获第四组,匹配1212
运行任意一个命令,都能得到你期望的输出结果。
内容的提问来源于stack exchange,提问作者iamarunk
相关产品推荐
相关产品推荐

