2011-03-12 58 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

保持简单和使用<([^>]*)>是一样快,因为它可以得到和适用于正则表达式的大多数版本。这是更快,因为它从来没有回溯,而使用<(.*?)>导致回溯。