正则表达式或条件在Swift中不起作用但适用于在线调试器

时间:2017-08-07 12:13:41

标签: regex swift

我正在尝试检查字符串是否包含一个额外字符或一个数字。但由于某种原因,它在Swift中不起作用,但它适用于在线调试器/编辑器。

这是我的正则表达式:^(?=.*[a-z])(?=.*[$@$#!%*?&])|(?=.*[0-9]).{6,}

据我所知:

^ - this is start anchor
(?=.*[a-z]) - string has one character
(?=.*[$@$#!%*?&]) - string has one special character
(?=.*[0-9]) - string has one digit
{6,} - string length is at least 6

在正则表达式验证中,常规|符号表示OR条件。

我的问题是为什么输出不是我想要的?

stackoverflow - false
stackoverflow1 - true 
stackoverflow@ - false // should be true
stackoverflow1@ - false // should be true

这就是我在swift中所做的事情:

func isPasswordValid(_ password : String) -> Bool{
    let passwordTest = NSPredicate(format: "SELF MATCHES %@", "^(?=.*[a-z])(?=.*[$@$#!%*?&])|(?=.*[0-9]).{6,}$")
    return passwordTest.evaluate(with: password)
}

要清楚,这就是我想要的:字符串长度必须至少为6个字符且至少有一个数字或额外字符。最好不要将字符限制为(?=.*[$@$#!%*?&])

1 个答案:

答案 0 :(得分:3)

您匹配的模式:1)包含至少1个小写ASCII字母和[...]内的至少1个特殊字符的字符串的开头,2)或匹配6个或更多字符的字符串至少有一位数。

另外,请注意MATCHES模式需要整个字符串匹配的事实,这是您的模式在Swift中失败的主要原因。

似乎你想要匹配一个包含6个或更多字符的字符串,并且应该包含至少1个数字或特殊字符(我看它可以是标点符号或符号)。

所以,你需要使用

"(?=.*[0-9\\p{S}\\p{P}]).{6,}"

请参阅regex demo。由于^模式需要完整的字符串匹配,因此无需$MATCHES

模式详情

  • (?=.*[0-9\\p{S}\\p{P}]) - 一个积极的先行者,要求在任何0之后应该有一个ASCII数字(0-9),标点符号(\p{P})或符号(\p{S})除了换行符之外的+字符(使用(?s)添加模式以允许.匹配换行符)
  • .{6,} - 任意六个或更多字符。