2011-05-15 85 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