我有一个包含大量不同邮政编码的文件:
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
匹配,因为“或”子句与该特定句子匹配。我很困惑为什么它在第一个12345
上不匹配,因为我的表达式应该说“匹配5个数字但忽略任何标点符号。”
答案 0 :(得分:9)
与您所需输出匹配的表达式为:
egrep "^[0-9]{5}([-][0-9]{4})?$" samplefile
表达分解:
^[0-9]{5}
- 找到以5位数开头的行。 ^
表示行首,[0-9]{5}
表示零到九之间的五位数。
([-][0-9]{4})?$
- 可能以短划线和四位数结束,或者根本不结束。 ()
将表达式组合在一起,[-]
表示短划线字符,[0-9]{4}
正好表示0到9之间的四位数,?
表示分组表达式完全存在或不存在并且$
标志着该行的结束。
<强> TEST.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
。这也适用于grep -F
,与fgrep
和grep -r
相同,与rgrep
相同。
答案 1 :(得分:0)
它不匹配“12345”但会匹配“12345a”。第一个句子需要以非标点字符结束,就像你编写它一样。
考虑迈克的回答;它更清楚。