使用正则表达式在iOS Swift上验证密码

使用正则表达式在iOS Swift上验证密码,ios,swift,regex,Ios,Swift,Regex,我需要根据以下要求验证用户密码: 8个或更多字符 包含1个字符和1个数字 可以输入字母、数字和符号 有人知道我如何使用正则表达式来实现这一点吗 我曾试图独自解决这个问题,但迄今为止,我什么也没做。下面是我最近一次尝试的代码 func isPasswordHasEightCharacter(密码:String)->Bool{ 让passWordRegEx=“^.{8,}$” 让passwordTest=NSPredicate(格式:“SELF MATCHES%@”,passWordRegEx)

我需要根据以下要求验证用户密码:

  • 8个或更多字符

  • 包含1个字符和1个数字

  • 可以输入字母、数字和符号

有人知道我如何使用正则表达式来实现这一点吗

我曾试图独自解决这个问题,但迄今为止,我什么也没做。下面是我最近一次尝试的代码

func isPasswordHasEightCharacter(密码:String)->Bool{
让passWordRegEx=“^.{8,}$”
让passwordTest=NSPredicate(格式:“SELF MATCHES%@”,passWordRegEx)
返回passwordTest.evaluate(使用:password)
}
func isPasswordHasNumberAndCharacter(密码:字符串)->Bool{
让passRegEx=“^(?=.[a-z])(?=.[0-9])”
让passwordTest=NSPredicate(格式:“SELF MATCHES%@”,passRegEx)
返回passwordTest.evaluate(使用:password)
}
func isPasswordHasNumberAndCharacterSign(密码:字符串)->Bool{
让passWordRegEx=“^(?。[^a-zA-Z0-9@${'$}^+=])”
让passwordTest=NSPredicate(格式:“SELF MATCHES%@”,passWordRegEx)
返回passwordTest.evaluate(使用:password)
}

主要问题是
NSPredicate
with
MATCHES
需要完整的字符串来匹配和使用整个输入。Lookarounds—您使用的是lookaheads—不使用文本,也就是说,它们匹配的文本不会添加到匹配值中,并且regex索引保持在尝试匹配lookaround模式之前的位置

最后两部分可以这样固定:

func isPasswordHasNumberAndCharacter(password: String) -> Bool {
    let passRegEx = "(?=[^a-z]*[a-z])[^0-9]*[0-9].*"
    let passwordTest = NSPredicate(format: "SELF MATCHES %@", passRegEx)
    return passwordTest.evaluate(with: password)
}

func isPasswordHasNumberAndCharacterSign(password: String) -> Bool {
    let passWordRegEx = "[a-zA-Z0-9!@#$%^&*]+"
    let passwordTest = NSPredicate(format: "SELF MATCHES %@", passWordRegEx)
    return passwordTest.evaluate(with: password)
}
第一部分还可以,不过您不需要
^
$
锚定(因为整个字符串输入必须与模式匹配)。但是,要检查字符串长度,甚至不需要正则表达式:请参阅

注:

  • ^(?=[^a-z]*[a-z])[^0-9]*[0-9]..\z
    匹配至少包含一个小写ASCII字母和至少一个ASCII数字的字符串
  • ^[a-zA-Z0-9!@$%^&*]+$
    将匹配仅包含ASCII字母、数字和某些特定符号的字符串。如果插入
    -
    ,请确保它位于末尾。如果您还需要添加它们,请同时转义
    [
    ]
如果您想将所有这些合并到一个正则表达式中,您可以使用

let passRegEx = "(?=[^a-z]*[a-z])(?=[^0-9]*[0-9])[a-zA-Z0-9!@#$%^&*]{8,}"
或者,如果您没有将正则表达式与
NSPredicate
匹配项一起使用,请使用锚定:

let passRegEx = "\\A(?=[^a-z]*[a-z])(?=[^0-9]*[0-9])[a-zA-Z0-9!@#$%^&*]{8,}\\z"

主要问题是
NSPredicate
with
MATCHES
需要完整的字符串来匹配和使用整个输入。Lookarounds—您使用的是lookaheads—不使用文本,也就是说,它们匹配的文本不会添加到匹配值中,并且regex索引保持在尝试匹配lookaround模式之前的位置

最后两部分可以这样固定:

func isPasswordHasNumberAndCharacter(password: String) -> Bool {
    let passRegEx = "(?=[^a-z]*[a-z])[^0-9]*[0-9].*"
    let passwordTest = NSPredicate(format: "SELF MATCHES %@", passRegEx)
    return passwordTest.evaluate(with: password)
}

func isPasswordHasNumberAndCharacterSign(password: String) -> Bool {
    let passWordRegEx = "[a-zA-Z0-9!@#$%^&*]+"
    let passwordTest = NSPredicate(format: "SELF MATCHES %@", passWordRegEx)
    return passwordTest.evaluate(with: password)
}
第一部分还可以,不过您不需要
^
$
锚定(因为整个字符串输入必须与模式匹配)。但是,要检查字符串长度,甚至不需要正则表达式:请参阅

注:

  • ^(?=[^a-z]*[a-z])[^0-9]*[0-9]..\z
    匹配至少包含一个小写ASCII字母和至少一个ASCII数字的字符串
  • ^[a-zA-Z0-9!@$%^&*]+$
    将匹配仅包含ASCII字母、数字和某些特定符号的字符串。如果插入
    -
    ,请确保它位于末尾。如果您还需要添加它们,请同时转义
    [
    ]
如果您想将所有这些合并到一个正则表达式中,您可以使用

let passRegEx = "(?=[^a-z]*[a-z])(?=[^0-9]*[0-9])[a-zA-Z0-9!@#$%^&*]{8,}"
或者,如果您没有将正则表达式与
NSPredicate
匹配项一起使用,请使用锚定:

let passRegEx = "\\A(?=[^a-z]*[a-z])(?=[^0-9]*[0-9])[a-zA-Z0-9!@#$%^&*]{8,}\\z"

在这个解决方案中,每个需求都被单独检查,以避免复杂的正则表达式。此解决方案支持字符的变体,如ệż等

func validatePassword(_ password: String) -> Bool {
    //At least 8 characters
    if password.count < 8 {
        return false
    }

    //At least one digit
    if password.range(of: #"\d+"#, options: .regularExpression) == nil {
        return false
    }

    //At least one letter
    if password.range(of: #"\p{Alphabetic}+"#, options: .regularExpression) == nil {
        return false
    }

    //No whitespace charcters
    if password.range(of: #"\s+"#, options: .regularExpression) != nil {
        return false
    }

    return true
}

在这个解决方案中,每个需求都被单独检查,以避免复杂的正则表达式。此解决方案支持字符的变体,如ệż等

func validatePassword(_ password: String) -> Bool {
    //At least 8 characters
    if password.count < 8 {
        return false
    }

    //At least one digit
    if password.range(of: #"\d+"#, options: .regularExpression) == nil {
        return false
    }

    //At least one letter
    if password.range(of: #"\p{Alphabetic}+"#, options: .regularExpression) == nil {
        return false
    }

    //No whitespace charcters
    if password.range(of: #"\s+"#, options: .regularExpression) != nil {
        return false
    }

    return true
}

你调试过你的函数了吗?到底发生了什么?是否抛出了任何错误?字母、数字和符号,您是指任何非空白字符吗?请检查@WiktorStribiżew yesOk,查看下面的答案。您是否调试了您的函数?到底发生了什么?出现任何错误?由字母、数字和符号引发,您是指任何非空白字符吗?请检查@WiktorStribiżew yesOk,查看下面的答案。我想要的最后一个函数仅包含字母、数字和符号,如(!@$%^&*)。当我输入特殊字符,如“|”,或片假名日语,然后返回false@Hiệ那么,你的意思是只匹配ASCII字母、数字和一些特定符号吗?我更新了答案。请检查。是的,当我输入一些字符时,我想显示消息:“输入了无效值”@HiệpChelsea那么,显示它。上面的函数现在应该可以工作了。现在你知道你的regexp失败的原因了。剩下的取决于你,与当前问题无关。现在我希望文本、顶部和最后一个非空白之间有空白。我尝试:^(?=\\S*)(?=\\S*)[a-zA-Z0-9!@$%^&*+(?=\\S*))$但不起作用。你能帮我吗?我想要的最后一个函数只包含字母、数字和符号,如(!@$%^&*)。当我输入特殊字符,如“|”,或者片假名日本人再回来false@Hiệ那么,你的意思是只匹配ASCII字母、数字和一些特定符号吗?我更新了答案。请检查。是的,当我输入一些字符时,我想显示消息:“输入了无效值”@Hiệ所以,展示给大家看。以上功能现在应该可以工作了。现在你知道为什么你的正则表达式失败了。其余部分由您决定,与当前问题无关。现在我希望文本、顶部和最后一个非空白之间有空白。我尝试:^(?=\\S*)(?=\\S*)[a-zA-Z0-9!@$%^&*]+(?=\\S*)$,但不起作用。你能帮助我吗?