2011-03-12 45 views
1

我有如下因素的字符串:user1 fam <[email protected]>, user2 fam <[email protected]>, ...幫助撰寫正則表達式

如何從這個字符串的正則表達式獲取郵件地址。我需要在郵件地址的輸出列表

[email protected] 
[email protected] 

我嘗試:

<.*> 

但它的輸出中與<>:

<[email protected]> 
    <[email protected]> 

謝謝。

p.s.謝謝@xanatos的評論,我用Erlang

+1

當你問正則表達式時,你總是應該總是寫你正在使用的語言(好吧,除非你問的是多種語言之間的比較:-))。有更多的Regex實現比天空中的星星或地球上的沙粒更多。 :-) – xanatos 2011-03-12 10:56:23

+1

你可能會考慮不使用正則表達式。如果直接在Erlang中定義狀態機,解析是相當簡單的。 – 2011-03-12 13:09:21

回答

1
  • 您需要使用的選項ungreedy,使其只相匹配的單獨支架對。

  • global這樣你就可以得到所有的匹配。

  • 並且您需要{capture, all_but_first, list}以便您獲得實際值(如果您更喜歡二元結果,則可以使用list,也可以使用binary)。 all_but_first告訴re不返回整個比賽(其中包括<>),只是組。

結果:

1> S. 
"user1 fam <[email protected]>, user2 fam <[email protected]>, " 
2> re:run(S, "<(.+)>", [ungreedy, global, {capture, all_but_first, list}]). 
{match,[["[email protected]"],["[email protected]"]]} 
4

正如其他人所說,但使它更快:

<([^>]*)> 

這樣的正則表達式就不必走回頭路(與其他的正則表達式的建議,正則表達式匹配所有字符串,然後將開始回滾找到一個>

我會補充說,由於歷史原因,.和,例如[\s\S]之間有小的差異。除了\n之外,它們都可以捕獲所有角色。第一個(.)沒有抓住它。因此,通過使用[^>]您正在捕獲\n,但這不應該成爲您正在做什麼的問題。 http://www.regular-expressions.info/dot.html

只要是完整的,因爲它是經常發生的問題,還有另一種變體:

<((?:(?!>).)*)> 

(你可以用[\s\S]替代.,如果你想,或者如果你的語言使用單線選項支持它,使.行爲以不同的方式)。這裏的要點是「停止」表達式可以長於一個字符。您可以插入(?!%%)而不是(?!>),它會停止在%%。但是我不確定這個變體是如何與Erlang一起工作的(我沒有注意到這個新標籤......當我初讀這個問題時,它不在那裏,我也不是Erlang的程序員......而且似乎至少2個二郎程序員對參數:-)不同意見)

+0

這不僅僅是最快的方式,它是**唯一的方式(除非你選擇指定它應該匹配的所有字符的白名單)。 – 2011-03-12 12:47:38

+0

@Alan ???你在說什麼?使用'[^>] *'而不是'。*?'或者什麼? – xanatos 2011-03-12 12:53:49

+0

我的意思是'<([^>] *)>'。當我寫這個評論時,答案中只有一個正則表達式。順便說一下,Erlang的正則表達式不支持lookahead,所以你的第二個產品將不起作用。 – 2011-03-12 13:10:44

1

保持簡單和使用<([^>]*)>是一樣快,因爲它可以得到和適用於正則表達式的大多數版本。這是更快,因爲它從來沒有回溯,而使用<(.*?)>導致回溯。