【问题标题】:Get all email addresses in a string with JavaScript使用 JavaScript 获取字符串中的所有电子邮件地址
【发布时间】:2010-05-06 08:06:05
【问题描述】:

所以,我有这个 JavaScript 函数:

ME.Utils = {
    RxEmail: new RegExp(/^(("[\w-\s]+")|([\w-]+(?:\.[\w-]+)*)|("[\w-\s]+")([\w-]+(?:\.[\w-]+)*))(@((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)$)|(@\[?((25[0-5]\.|2[0-4][0-9]\.|1[0-9]{2}\.|[0-9]{1,2}\.))((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[0-9]{1,2})\.){2}(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[0-9]{1,2})\]?$)/i),

    ValidateEmail: function(email) {
        return ME.Utils.RxEmail.test(email);
    },

    GetEmailAddresses: function(text) {
        return text.match(ME.Utils.RxEmail);
    },

    HasEmail: function(text) {
        return ME.Utils.GetEmailAddresses != null;
    }
};

ValidateEmail 效果很好。但是,HasEmailGetEmailAddresses 无法正常工作。

GetEmailAdresses 始终返回 null,除非字符串仅包含电子邮件地址。在这种情况下,GetEmailAdresses 返回一个数组,不仅包含电子邮件地址,还包含电子邮件地址 (test@test.com),仅包含 id (test) 以及一些未识别的等...

你能帮我弄清楚我的表达有什么问题吗?

【问题讨论】:

  • 哦,看。有人正在尝试使用正则表达式测试电子邮件地址。我最后一次看到成功的人是什么时候?不是今天,它会拒绝带有 + 字符的电子邮件地址。
  • 请不要再嘲笑我了。帮帮我,或者什么都不说……
  • @odeo,没那么简单。见ex-parrot.com/~pdw/Mail-RFC822-Address.htmlstackoverflow.com/questions/201323/…,甚至那个怪物也需要先进行一些剥离
  • 关于定期在此处使用正则表达式裁剪解析电子邮件地址的问题,它们通常对常见的地址样式有误报。我不是在嘲笑你,我是在对人们未能从历史中吸取教训并一遍又一遍地犯同样的错误表示沮丧。正则表达式不适合深入解析电子邮件地址,但人们坚持一次又一次地尝试和失败。雅虎!是一家以网络为基础的大公司,但他们无法做到正确:twitter.com/edent/status/11687784947 - 但许多小鱼认为他们可以。

标签: javascript regex validation


【解决方案1】:

有一些问题。

  1. 您的正则表达式锚定在字符串的开头和结尾。您应该从中删除 ^$ 字符。

  2. 如果您只想返回电子邮件地址,请使用非捕获组。

  3. HasEmail() 中,您没有调用GetEmailAddresses()。您实际上是在检查该属性的值是否已定义。

总而言之,固定版本可能如下所示:

ME.Utils = {
    RxEmail: /(?:(?:"[\w-\s]+")|(?:[\w-]+(?:\.[\w-]+)*)|(?:"[\w-\s]+")(?:[\w-]+(?:\.[\w-]+)*))(?:@(?:(?:[\w-]+\.)*\w[\w-]{0,66})\.(?:[a-z]{2,6}(?:?:\.[a-z]{2})?))|(?:@\[?(?:(?:25[0-5]\.|2[0-4][0-9]\.|1[0-9]{2}\.|[0-9]{1,2}\.))(?:(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[0-9]{1,2})\.){2}(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[0-9]{1,2})\]?)/gi,

    ValidateEmail: function(email) {
        // We can't do a simple test() since we're using an unanchored regex now.
        var match = ME.Utils.RxEmail.match(email);
        return match.length == 1 && match[0] == email;
    },

    GetEmailAddresses: function(text) {
        return text.match(ME.Utils.RxEmail);
    },

    HasEmail: function(text) {
        return ME.Utils.GetEmailAddresses(text) != null;
    }
};

【讨论】:

    【解决方案2】:

    您的正则表达式专门匹配整个字符串

    RxEmail: new RegExp(/^ ... $)/i),
    

    ^ 和 $ 分别匹配输入的开始和结束。尝试删除这些字符,看看效果如何?

    【讨论】:

    • 谢谢。除此之外,您的答案更完整,所以哥们也为您+1 :)
    【解决方案3】:
    if (emailMatch = ME.Utils.GetEmailAddresses(myEmail))
      // do stuff with emailMatch[1]
    

    【讨论】:

    • 不是很有帮助。我需要得到一个包含字符串中所有电子邮件地址的数组,例如 ["test@test.com", "sth@sth.com", etc@etc.com"]。现在 GetEmailAddresses 返回一个充满垃圾的数组。
    【解决方案4】:

    使用电子邮件地址显示数组时,您会在数组中获得多个条目的原因是您的表达式中有捕获组。在 Javascript 中,匹配的结果是一个数组,其中索引 0 是匹配的总字符串,然后每个捕获组都有(可选)附加索引。您可以通过将群组从 (...) 更改为 (?:...) 来使您的群组不被捕获。

    至于为什么在使用GetEmailAddresses 和字符串包含 电子邮件地址时没有得到预期的结果,试试这个:

    GetEmailAddresses: function(text) {
        var rv = [];
        var match;
    
        while (match = ME.Utils.RxEmail.exec(text)) {
            rv.push(match[0]);
        }
        return rv.length == 0 ? null : rv;
    },
    

    看到这个question and answer,我不能说我知道为什么String#match 和上面的RegExp#exec 循环不太一样,但事实并非如此。

    编辑您还需要修复oedo pointed out 的问题;需要允许 RegExp 匹配子字符串。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-21
      • 2012-07-05
      • 2017-10-10
      • 2023-04-03
      • 2013-11-22
      • 1970-01-01
      相关资源
      最近更新 更多