我有一個文件,我需要過濾具有(或不具有)N次出現的模式的行。 也就是說,如果我的模式是字母o
,我什麼以匹配信o
恰好出現4次線,表達式應該匹配第一個下面的示例中的行而不是其他:在同一行匹配具有n次模式的行
foo foo
foo
foo foo foo
我thouth我可以在vim或sed,awk或其他工具中使用正則表達式來實現。 我google了,並沒有發現任何人做過類似的事情。 可能會做一個腳本或類似的東西來解析每一行。 有沒有人做過類似的事情?
感謝
我有一個文件,我需要過濾具有(或不具有)N次出現的模式的行。 也就是說,如果我的模式是字母o
,我什麼以匹配信o
恰好出現4次線,表達式應該匹配第一個下面的示例中的行而不是其他:在同一行匹配具有n次模式的行
foo foo
foo
foo foo foo
我thouth我可以在vim或sed,awk或其他工具中使用正則表達式來實現。 我google了,並沒有發現任何人做過類似的事情。 可能會做一個腳本或類似的東西來解析每一行。 有沒有人做過類似的事情?
感謝
您可以使用正則表達式象下面這樣:
(?=(.*o){4})(?!(.*o){5,}).*
Regexr - http://regexr.com?2toro
這應該你想要的任何圖案的工作。例如,你想找到它正好四個FOOS線,使用方法:
(?=(.*foo){4})(?!(.*foo){5,}).*
Regexr - http://regexr.com?2tosa
這是可能的,但不容易。
對於單個字母的情況,諸如^[^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])*
。但是,如果單詞更長,並且必須匹配四次,您可以看到這會變得令人討厭。
不工作,坦率地說,太複雜,不負擔工作 - http://regexr.com?2tos1 – manojlds 2011-05-15 01:13:51
perl -lnwe '@c=$_=~/o/g;if(scalar(@c)==4){print $_}' file_to_parse
你的答案工作正常,但我投M42答案是正確的,因爲它比你的短。我投票認爲你的有用。謝謝。 – lodge 2011-05-15 22:01:32
在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 }'
我使用了M42的perl答案,但是你的工作也是如此,所以我投它爲有用。謝謝。 – lodge 2011-05-15 22:01:19
如果你想編寫代碼,那麼你可以構建一個基於DFA的字符串匹配,或者我會告訴你看一下你可以輕鬆編寫的shift或字符串匹配算法。然後您可以根據算法需要將字符串輸入到適當的數據結構。對於移位或字符串匹配算法,請閱讀http://en.wikipedia.org/wiki/Shift_Or_Algorithm。
'grep -E -x'([^ o] * o){4} [^ o] *'' – 2011-05-16 14:57:29