【问题标题】:Email Validation is wrong as per Regex根据正则表达式,电子邮件验证是错误的
【发布时间】:2017-06-12 18:26:24
【问题描述】:

我在我的项目中使用电子邮件验证,方法如下所示

//MARK: isValidEmailID
    func isValidEmail(testStr:String) -> Bool {
        print("validate emilId: \(testStr)")
        let emailRegEx = "^(?:(?:(?:(?: )*(?:(?:(?:\\t| )*\\r\\n)?(?:\\t| )+))+(?: )*)|(?: )+)?(?:(?:(?:[-A-Za-z0-9!#$%&’*+/=?^_'{|}~]+(?:\\.[-A-Za-z0-9!#$%&’*+/=?^_'{|}~]+)*)|(?:\"(?:(?:(?:(?: )*(?:(?:[!#-Z^-~]|\\[|\\])|(?:\\\\(?:\\t|[ -~]))))+(?: )*)|(?: )+)\"))(?:@)(?:(?:(?:[A-Za-z0-9](?:[-A-Za-z0-9]{0,61}[A-Za-z0-9])?)(?:\\.[A-Za-z0-9](?:[-A-Za-z0-9]{0,61}[A-Za-z0-9])?)*)|(?:\\[(?:(?:(?:(?:(?:[0-9]|(?:[1-9][0-9])|(?:1[0-9][0-9])|(?:2[0-4][0-9])|(?:25[0-5]))\\.){3}(?:[0-9]|(?:[1-9][0-9])|(?:1[0-9][0-9])|(?:2[0-4][0-9])|(?:25[0-5]))))|(?:(?:(?: )*[!-Z^-~])*(?: )*)|(?:[Vv][0-9A-Fa-f]+\\.[-A-Za-z0-9._~!$&'()*+,;=:]+))\\])))(?:(?:(?:(?: )*(?:(?:(?:\\t| )*\\r\\n)?(?:\\t| )+))+(?: )*)|(?: )+)?$"
        let emailTest = NSPredicate(format:"SELF MATCHES %@", emailRegEx)
        let result = emailTest.evaluateWithObject(testStr)
        return result
    }

func isValidEmailID(email: String) -> Bool {
        let regExPattern: String = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}"
        let emailValidator: NSPredicate = NSPredicate(format: "SELF MATCHES %@", regExPattern)
        let isValid: Bool = emailValidator.evaluateWithObject(email)
        return isValid
    }

当我输入“modijecky@gmail.com”或任何其他错误输入时,这两个正则表达式都可以正常工作,但当我输入“modijecky@gmail.com.com”时它不会工作。

所以,我发现“name@.com.com”是一个有效的电子邮件地址,并且有更多这样的子域。所以现在我希望用户不要输入子域。是否有任何 REGEX 仅在一个域中验证电子邮件地址,例如“name@gmail.com”,而不是多个域或子域。

我还尝试了来自谷歌的不同正则表达式并将其实施到项目中,但出现了同样的问题。
请帮帮我。
谢谢

【问题讨论】:

  • 为什么modijecky@gmail.com.com 应该是错误的? com.comgmail.com.com 一样是有效域。见:en.wikipedia.org/wiki/Email_address#Examples
  • 验证电子邮件的唯一安全方法是发送电子邮件并等待返回。
  • 请查看我更新的答案

标签: ios regex swift email-validation


【解决方案1】:

函数调用:

let result = isValidEmail(testStr: "test@test.com.op")
        if (result)
        {
            print ("passed")
        }
        else{
            print ("failed")
        }

功能定义:

func isValidEmail(testStr:String) -> Bool {
        // print("validate calendar: \(testStr)")
        var returnValue : Bool = false
        let emailRegEx = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}"
        let emailTest = NSPredicate(format:"SELF MATCHES %@", emailRegEx)
        if (emailTest.evaluate(with: testStr))
        {
            let fullNameArr = testStr.components(separatedBy: "@")
            let IdName    = fullNameArr[0]
            let domainName = fullNameArr[1]
            var number = 0
            let string = domainName
            for character in domainName.characters {
                if character == "."
                {
                    number = number + 1
                }
            }
            if number <= 1
            {
                returnValue = true
            }
        }
        return returnValue
    }

结果:

【讨论】:

  • 同样的问题,当我输入“name@gmail.com.com”时它会返回true。对不起,伙计,但它不起作用
  • 我在我的问题中告诉我我不想要子域,我想只使用像“name@gmail.com”这样的一个域而不是像“name@gmail.com”这样的子域。 com'
  • 是的,伙计,我不要.com.com,我只想要一个.com
  • 不是字符,我的意思是有.com、.edu、.fr、.in 等域,但只有一个域而不是两个域。域中会有很多字符,但只有一个
【解决方案2】:

不要重新发明轮子:

Not Reinventing the Wheel: Email Validation in Swift

基本上,您可以使用 NSDataDetector 来完成繁重的工作,并使所有内容保持一致并更新到它在 macOS 和 iOS 中的本机工作方式。不仅如此,您还可以避免正则表达式的麻烦。

// Simplifying the example from the website a bit

import Foundation

func validate(_ text: String) -> Bool {
  let types = NSTextCheckingResult.CheckingType.link.rawValue
  guard
    let dataDetector = try? NSDataDetector(types: types),
    let match = dataDetector
      .matches(in: text, options: [], range: NSRangeFromString(text))
      .first,
    let absoluteString = match.url?.absoluteString
    else { return false }
  return absoluteString == "mailto:\(text)"
}

validate("test@gmail.com")  // -> true
validate(" test@gmail.com") // -> false

这将确保整个文本是一个没有任何多余字符的单一有效电子邮件地址。

【讨论】:

  • 这是否在内部验证邮件 ID?
  • 我还没有详尽地通过测试用例运行它,但它似乎捕获了最常见的错误地址。
  • 我也会用它来代替正则表达式似乎不太容易出错和干净感谢分享。 :)
【解决方案3】:

你应该有这个代码不允许子域。

    func isValidEmail(email:String) -> Bool {

    if email.range(of: "@") == nil || email.range(of: ".") == nil{
        return false
    }

    let accountName = email.substring(to: email.range(of: "@")!.lowerBound)

    let domainName = email.substring(from: email.range(of: "@")!.upperBound)

    let subDomain = domainName.substring(from: email.range(of: ".")!.lowerBound)



    //filter for user name
    let unWantedInUName = " ~!@#$^&*()={}[]|;’:\"<>,?/`";
    //filter for domain
    let unWantedInDomain = " ~!@#$%^&*()={}[]|;’:\"<>,+?/`";
    //filter for subdomain
    let unWantedInSub = " `~!@#$%^&*()={}[]:\";’<>,?/1234567890";

    //subdomain should not be less that 2 and not greater 6
    if(!(subDomain.characters.count>=2 && subDomain.characters.count<=6)) {
        return false;
    }

    if (accountName == "" || accountName.rangeOfCharacter(from: CharacterSet.init(charactersIn: unWantedInUName)) != nil ||  domainName == "" || domainName.rangeOfCharacter(from: CharacterSet.init(charactersIn: unWantedInDomain)) != nil || subDomain == "" || subDomain.rangeOfCharacter(from: CharacterSet.init(charactersIn: unWantedInSub)) != nil ) {
        return false
    }

    return true
}

【讨论】:

  • 我会检查它,然后告诉你它是否工作。
  • 确定我已经在操场上测试过 :)
  • @JeckyModi modi 是否有效,如果有任何问题,请告诉我??
  • 不带点的电子邮件完全有效,例如 me@localhostwhatever_is_your_name@com 请参阅:en.wikipedia.org/wiki/Email_address#Examples
猜你喜欢
  • 2015-08-07
  • 1970-01-01
  • 2014-04-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-05
相关资源
最近更新 更多