2014-12-27 47 views
3

我只是好奇爲什麼grep以這種方式匹配事情。grep-爲什麼背部引用周圍必須存在單詞邊界?

例如,假設我試圖找到一個在句子中出現兩次的單詞(而不是其他單詞的一部分)。所以我想找到像下面幾行:

hello everybody hello 

,而不是像下面這樣:

hello everybody hellopeople 

那麼爲什麼下面的grep表達工作:

grep -E '(\<.*\>).*\<\1\>' file 

,而不是如下:

grep -E '(\<.*\>).*\1' file 

我原以爲第二個可以工作,因爲字邊界(\ <和\>)位於第二個匹配的括號內,但不是。看起來相當混亂,人們必須在後面的引用中加上詞語邊界,有人可以解釋爲什麼grep以這種方式匹配行,或者可能進一步闡述這個想法嗎?

回答

4

無法在捕獲組中捕獲零寬度斷言/零長度匹配。 \b or \< \>是零長度匹配。它不能在組中捕獲。與零寬度斷言相同,如向後看/向前看。

例如:

((?<=#)\w+(?=#)).*\1 

將匹配字符串

#hello# everybody hellofoo 

附:您可能希望在字詞邊界內使用\w+而不是.*

-2

如果您沒有得到任何好的grep解決方案,您可以使用awk來解決這個問題。

awk '{for (i=1;i<=NF;i++) if (a[$i]++) print $i;delete a}' 
hello 

如果一個單詞在一行中存在多次,請將其打印出來。

+2

Imo OP問題_「......有人可以解釋爲什麼grep會以這種方式匹配行[?]」_與您的答案無關(ps:沒有對我的部分降價......) – gboffi 2014-12-27 22:13:18

+0

此外,您的答案假設單詞之間用空白分隔,而在文本中單詞之間也用不同的標點符號分隔。 – gboffi 2014-12-27 22:19:45

+0

@gboffi它可以同時處理空格和製表符,並處理開始和結束的單詞。經常用新的眼睛看東西有助於對問題進行分類。只有當它的學校工作和OP需要'grep'時,我才能看到這無濟於事。幾乎所有使用'bash'的系統都有'sed','awk'等等。有時使用其他程序會有更好的解決方案。 – Jotne 2014-12-27 22:24:25

相關問題