用于正则表达式模式匹配崩溃的 NSPredicate

Posted

技术标签:

【中文标题】用于正则表达式模式匹配崩溃的 NSPredicate【英文标题】:NSPredicate for regex pattern matching crashes 【发布时间】:2016-03-12 12:34:11 【问题描述】:

这段代码:

 internal let emailRegex:String = "[A-Z0-9a-z._%+-]+[A-Za-z0-9.-]+\\.[A-Za-z]2,5"

 let emailText = NSPredicate(format: "SELF MATCHES \(emailRegex)")

 return emailText .evaluateWithObject(email)

因错误而崩溃:

'NSInvalidArgumentException',原因:'无法解析格式 字符串“自匹配 [A-Z0-9a-z._%+-]+[A-Za-z0-9.-]+.[A-Za-z]2,5”'

【问题讨论】:

一些关于电子邮件验证的好读物,它可能无法帮助您解决问题,但可以帮助您避免其他问题:I Knew How To Validate An Email Address Until I Read The RFC 【参考方案1】:

这是本地处理电子邮件验证的好方法:

Handling email validation using built-in functionality

我也有这种方式用正则表达式来处理它:

这是来自I Knew How To Validate An Email Address Until I Read The RFC的正则表达式

import Foundation

let pattern = "^(?!\\.)(\"([^\"\\r\\\\]|\\\\[\"\\r\\\\])*\"|([-a-z0-9!#$%&'*+/=?^_`|~]|(?<!\\.)\\.)*)(?<!\\.)@[a-z0-9][\\w\\.-]*[a-z0-9]\\.[a-z][a-z\\.]*[a-z]$"
let predicate = NSPredicate(format: "SELF MATCHES %@", pattern)

// tests in the format (email, isValid)
let tests = [
  ("NotAnEmail", false),
  ("@NotAnEmail", false),
  ("\"test\\\rblah\"@example.com", true),
  ("\"test\rblah\"@example.com", false),
  ("\"test\\\"blah\"@example.com", true),
  ("\"test\"blah\"@example.com", false),
  ("customer/department@example.com", true),
  ("$A12345@example.com", true),
  ("!def!xyz%abc@example.com", true),
  ("_Yosemite.Sam@example.com", true),
  ("~@example.com", true),
  (".wooly@example.com", false),
  ("wo..oly@example.com", false),
  ("pootietang.@example.com", false),
  (".@example.com", false),
  ("\"Austin@Powers\"@example.com", true),
  ("Ima.Fool@example.com", true),
  ("\"Ima.Fool\"@example.com", true),
  ("\"Ima Fool\"@example.com", true),
  ("Ima Fool@example.com", false)]

for (index,(email,isValid)) in tests.enumerate() 
  let eval = predicate.evaluateWithObject(email)
  if eval == isValid 
    print(index, ": VALID!")
  

输出:

0 : VALID!
1 : VALID!
2 : VALID!
3 : VALID!
4 : VALID!
5 : VALID!
6 : VALID!
8 : VALID!
10 : VALID!
11 : VALID!
12 : VALID!
13 : VALID!
14 : VALID!
15 : VALID!
17 : VALID!
18 : VALID!
19 : VALID!

【讨论】:

【参考方案2】:

此外,您的我还有另一个电子邮件正则表达式,您可以使用。

func isValidEmail() -> Bool 

    let regex = NSRegularExpression(pattern: "^[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]2,4$",
                options: [.CaseInsensitive])

    return regex.firstMatchInString(self, options:[],
        range: NSMakeRange(0, emailString.characters.count)) != nil

请检查此正则表达式。

【讨论】:

你能解释一下什么是utf16.count吗? 感谢它通过将 utf16.count 更改为 email.characters.count 来工作 @Sohil R. Memon 将向我解释什么是“尝试!”表示在 'let regex =' 语句中。【参考方案3】:

我终于找到了问题的解决方法

func isValidEmail(email:String) -> Bool



    let regex = try! NSRegularExpression(pattern: "^[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]2,4$",
        options: [.CaseInsensitive])

    return regex.firstMatchInString(email, options:[],
        range: NSMakeRange(0, email.characters.count)) != nil



【讨论】:

【参考方案4】:

NSPredicate 的正确使用方式是

import Foundation

let emailAddress = "mailbox@example.com"
let pattern = "^.+@([A-Za-z0-9-]+\\.)+[A-Za-z]2[A-Za-z]*$"
let predicate = NSPredicate(format: "SELF MATCHES %@", argumentArray: [pattern])
let isValidEmailAddress = predicate.evaluate(with: emailAddress)
print(isValidEmailAddress)

不过,地址验证方法的选择完全不同。

【讨论】:

以上是关于用于正则表达式模式匹配崩溃的 NSPredicate的主要内容,如果未能解决你的问题,请参考以下文章

用于匹配单词的 javascript 正则表达式模式,具有自定义单词边界

正则表达式的全局匹配模式

Linux的正则表达式

php正则表达式

匹配大量不同的句子(使用正则表达式模式解析)

正则-简单的模式