在同一行中将线条与图案匹配n次

时间:2011-05-15 00:55:06

标签: regex vim sed awk grep

我有一个文件,我需要过滤具有(或没有)N次出现的模式的行。 也就是说,如果我的模式是字母o,并且我要匹配字母o恰好出现4次的行,那么表达式应匹配以下示例行中的第一行但不匹配其他行:

foo foo  
foo  
foo foo foo   

我可以用vim,sed,awk或任何其他工具中的正则表达式来完成它。 我用谷歌搜索,并没有发现任何人做过类似的事情。 可能会做一个脚本或类似的东西来解析每一行。 有没有人做过类似的事情?

由于

6 个答案:

答案 0 :(得分:5)

您可以使用如下所示的正则表达式:

(?=(.*o){4})(?!(.*o){5,}).*

Regexr - http://regexr.com?2toro

这适用于您想要的任何模式。例如,您想要找到其中包含四个foos的行,请使用:

(?=(.*foo){4})(?!(.*foo){5,}).*

Regexr - http://regexr.com?2tosa

答案 1 :(得分:3)

perl -lnwe '@c=$_=~/o/g;if(scalar(@c)==4){print $_}' file_to_parse

答案 2 :(得分:3)

Perl one-liner:

perl -ne 'print if(tr/o/o/ == 4)' foo_file

答案 3 :(得分:2)

在awk ......

awk '{ if (gsub(/o/, "o") == 4) print }' # lines that matched
awk '{ if (gsub(/o/, "o") != 4) print }' # lines that didn't

如果您要使用不同的模式/匹配计数一遍又一遍地执行此操作,并且模式不是正则表达式,您还可以执行类似...

awk -v pattern=o -v matches=4 '{ if (gsub(pattern, pattern) == matches) print }'

答案 4 :(得分:0)

如果你想编写代码,那么你可以构建一个基于DFA的字符串匹配,或者我会告诉你看一下你可以轻松编写的移位或字符串匹配算法。然后,您可以根据算法需要将字符串输入到正确的数据结构中。请阅读http://en.wikipedia.org/wiki/Shift_Or_Algorithm以了解移位或字符串匹配算法。

答案 5 :(得分:-1)

这是可能的,但并不容易。

对于单字母大小写,^[^o]*o[^o]*o[^o]*o[^o]*o[^o]*$这样的表达式可以正常工作。它基本上寻找“不是o”(零或更多),然后是“o”四次,并在结尾处允许额外的“非o”字符。

但是更长的表达方式有点问题。例如,为了不找到单词“foo”,你必须允许“f”和“fo”而不是“foo”。因此,为了找到一个只有两次“foo”的行,你必须允许“ffofofoofoffoffoofoffofofo”这一行并不容易定义。

要匹配“除'foo'之外的任何东西”,您可以使用允许“f”和“fo”等表达式([^f]|f[^o]|fo[^o])*,而不是“foo”。但你可以看到如果这个词更长并且你必须匹配它四次会如何变得烦人。