2015-10-19 45 views
1
def get_hashtags(post) 
    tags = [] 
    post.scan(/(?<![0-9a-zA-Z])(#+)([a-zA-Z]+)/){|x,y| tags << y} 
    tags 
end 

Test.assert_equals(get_hashtags("two hashs##in middle of word#"), []) 
#Expected: [], instead got: ["in"] 

如果它不看後面,看是否匹配犯規用一個詞或數字開頭?爲什麼它仍然接受'in'作爲有效的匹配?爲什麼這個消極看起來後面錯了?

+3

因爲該模式成功的第二個#(這不是前面有'[0-9a-zA-Z]')。 –

回答

2

您應該使用\K而不是負向倒序。這使您可以大大簡化您的正則表達式:不需要預定義數組,捕獲組或塊。

\K表示「丟棄目前爲止所有匹配的東西」。這裏的關鍵是,可變長度匹配之前可以\K,而(在Ruby和大多數其它語言)可變長度的匹配沒有在(負或正)lookbehinds允許的。如果我不寫在擴展模式正則表達式

r =/
    [^0-9a-zA-Z#] # do not match any character in the character class 
    \#+   # match one or more pound signs 
    \K   # discard everything matched so far 
    [a-zA-Z]+  # match one or more letters 
    /x   # extended mode 

注意#\#+不需要逃脫。

"two hashs##in middle of word#".scan r 
    #=> [] 

"two hashs&#in middle of word#".scan r 
    #=> ["in"] 

"two hashs#in middle of word&#abc of another word.###def ".scan r 
    #=> ["abc", "def"] 
+0

我一直在尋找這個解決方案,現在已經很久了。謝了哥們。 – UsamaMan

相關問題