我有一个关于正则表达式的快速(希望很简单)问题。我正在尝试考虑一个匹配所有一组标记(无论顺序如何)的正则表达式。
例如,我有一个包含美国各州名称的文件
Abbreviation:State name:Capital:Became a state
AL:Alabama:Montgomery:December 14, 1819
AK:Alaska:Juneau:January 3, 1959
AZ:Arizona:Phoenix:February 14, 1912
...
WI:Wisconsin:Madison:May 29, 1848
WY:Wyoming:Cheyenne:July 10, 1890
假设我想查找名称中包含字母“A”、“R”和“N”的所有州(不区分大小写)。
我可以做一个
$ cut -d: -f2 states.txt | tail -n +2 | grep -i a | grep -i r | grep -i n
果然产生了
Arizona
Arkansas
California
Maryland
Nebraska
New Hampshire
North Carolina
North Dakota
Rhode Island
South Carolina
Virginia
West Virginia
如果所有三个字母以任何顺序出现,是否有任何方法可以使用单个正则表达式来匹配它们?
答案1
你应该使用awk
:
$ awk '/a|A/ && /R|r/ && /N|n/' file
Arizona
Arkansas
California
Maryland
Nebraska
New Hampshire
North Carolina
North Dakota
Rhode Island
South Carolina
Virginia
West Virginia
通过gawk
,您可以使用忽略大小写:
gawk '/a/ && /r/ && /n/' IGNORECASE=1 file
答案2
该grep
命令没有适当的 AND 运算符,因此在尝试解决此类问题时必须发挥创造力。您可以这样做,就像您选择这样做并将多个链接grep
在一起一样。但你也可以这样做:
$ echo -e "arie\narin" | grep -i '[arn].*[arn].*[arn]'
arin
这将匹配包含 a、r 或 n 组合的任何字符串,并且它必须包含此集合中出现 3 次的字符。
带空格的单词
要处理空格,您可以像这样调整上面的正则表达式:
$ echo -e "arie\narin\nar nie" | \
grep -i '[arn][[:alpha:]]*[arn][[:alpha:]]*[arn]'
arin
在这里,我们没有接受块之间的任何类型的字符,而是[arn]
更有选择性,只从[[:alpha:]]
集合中获取字符。此外,我们还告诉grep
我们,我们想要*
,即中间有零个或多个这些字符。
答案3
cut -d: -f2 states.txt | tail -n +2 | egrep -i '[arn].*[arn].*[arn]'
答案4
好吧,一个选择是,sed
尽管这可能比grep
替代方案慢得多
cut -d: -f2 states.txt | tail -n +2 | sed -n -e '/a/I{/r/I{/n/Ip}}'
Arizona
Arkansas
California
Maryland
Nebraska
New Hampshire
North Carolina
North Dakota
Rhode Island
South Carolina
Virginia
West Virginia