我有一个文件,其中包含一堆不同的邮政编码:
12345
12345-6789
1234567890
12345:6789
12345-7890
12:1234678
我只想匹配格式为 12345
或 12345-6789
的代码,但忽略所有其他形式。
我的正则表达式为:
grep -E '<[0-9]{5}>[^[:punct:]]|<[0-9]{5}>-[0-9]{4}' samplefile
它在12345-6789
上匹配,因为"or"子句在该特定子句上匹配。我很困惑为什么它在第一个12345
不匹配,因为我的表达式应该说"匹配 5 个数字但忽略任何标点符号"。
与所需输出匹配的表达式为:
egrep "^[0-9]{5}([-][0-9]{4})?$" samplefile
表达式细分:
^[0-9]{5}
- 查找以 5 位数字开头的行。 ^
表示行的开头,[0-9]{5}
表示 0 到 9 之间的正好五位数字。
([-][0-9]{4})?$
- 可能以破折号和四位数字结尾,或者什么都不做。 ()
将表达式组合在一起,[-]
表示短划线字符,[0-9]{4}
表示 0 到 9 之间的四位数字,?
表示分组表达式完全存在或不存在,$
标记行尾。
测试.dat
12345
12345-6789
1234567890
12345:6789
12345-7890
12:1234678
对测试数据运行表达式:
mike@test:~$ egrep "^[0-9]{5}([-][0-9]{4})?$" test.dat
12345
12345-6789
12345-7890
附加信息:grep -E
也可以写成egrep
。这也适用于与fgrep
相同的grep -F
和与rgrep
相同的grep -r
。
它不会匹配"12345",但会匹配"12345a"。第一个子句需要以非标点符号结尾,就像你写它的方式一样。
考虑一下迈克的答案;它更清楚了。