正则表达式匹配所有标记,与顺序无关

正则表达式匹配所有标记,与顺序无关

我有一个关于正则表达式的快速(希望很简单)问题。我正在尝试考虑一个匹配所有一组标记(无论顺序如何)的正则表达式。

例如,我有一个包含美国各州名称的文件

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

相关内容