2011-05-15 54 views
3

我有一个文件,我需要过滤具有(或不具有)N次出现的模式的行。 也就是说,如果我的模式是字母o,我什么以匹配信o恰好出现4次线,表达式应该匹配第一个下面的示例中的行而不是其他:在同一行匹配具有n次模式的行

foo foo 
foo 
foo foo foo 

我thouth我可以在vim或sed,awk或其他工具中使用正则表达式来实现。 我google了,并没有发现任何人做过类似的事情。 可能会做一个脚本或类似的东西来解析每一行。 有没有人做过类似的事情?

感谢

+0

'grep -E -x'([^ o] * o){4} [^ o] *'' – 2011-05-16 14:57:29

回答

3

一个Perl的一行:

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

我投你的答案为正确,而不是Timofey Stolbov的答案,因为你的答案更短。谢谢。 – lodge 2011-05-15 22:01:04

+0

@lodge:谢谢。 – Toto 2011-05-16 07:42:43

4

您可以使用正则表达式象下面这样:

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

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

这应该你想要的任何图案的工作。例如,你想找到它正好四个FOOS线,使用方法:

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

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

+0

我认为你的模式在'ooooo'中失败。 – MByD 2011-05-15 01:09:16

+0

@MByD - 怎么样? http://regexr.com?2toru – manojlds 2011-05-15 01:11:15

+0

我不熟悉这个网站,我会看看它。顺便说一句 - 你在哪里看到结果呢? – MByD 2011-05-15 01:12:44

-1

这是可能的,但不容易。

对于单个字母的情况,诸如^[^o]*o[^o]*o[^o]*o[^o]*o[^o]*$的表达式可以工作。它基本上寻找“不o”(零或更多),然后是“o”四次,并允许在末尾多出“不o”字符。

但更长的表达式是一个问题。例如,为了不找到“foo”这个词,你必须允许“f”和“fo”而不是“foo”。因此,要找到一个正好具有两次“foo”的行,您必须允许“foffofofoffoffofofofofofo”这个不容易定义的行。

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

+0

不工作,坦率地说,太复杂,不负担工作 - http://regexr.com?2tos1 – manojlds 2011-05-15 01:13:51

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

你的答案工作正常,但我投M42答案是正确的,因为它比你的短。我投票认为你的有用。谢谢。 – lodge 2011-05-15 22:01:32

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 }' 
+0

我使用了M42的perl答案,但是你的工作也是如此,所以我投它为有用。谢谢。 – lodge 2011-05-15 22:01:19

0

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

相关问题