【问题标题】:Swift regex for checking if string has at least one uppercase letter用于检查字符串是否至少有一个大写字母的 Swift 正则表达式
【发布时间】:2017-06-16 14:54:13
【问题描述】:

我尝试了几种方法,例如:

^(?=.*?[A-Z])
^(?=.*?[A-Z])$
^(.*?[A-Z])$

没有用

static func atLeastOneUpperCase(_ input: String) -> Bool {
    return NSPredicate(format: "SELF MATCHES %@", upperCaseRegex).evaluate(with: input)
}

输入应该是上述之一。

【问题讨论】:

  • 给一些样本正负匹配
  • 我看不出第一个正则表达式不起作用的原因。你确定你使用正确吗?

标签: regex swift uppercase


【解决方案1】:

在 Swift 中,当您使用 NSPredicateMATCHES 时,您需要完整的字符串匹配

所以,在你的情况下,你需要使用

let upperCaseRegex = "(?s)[^A-Z]*[A-Z].*"

这将匹配一个以 0+ 字符而不是大写 ASCII 字母开头的整个字符串,然后将匹配 1 个 ASCII 字母,然后将匹配任何 0+ 字符(因为 (?s) 允许点匹配任何字符,包括行中断字符)。

另一种方法是使用range(of:options:range:locale:),传递.regularExpression 选项:

return input.range(of: "[A-Z]", options: .regularExpression) != nil

这将允许以非锚定方式匹配正则表达式,即这样,正则表达式引擎将寻找 部分 匹配,并且不再需要完整的字符串匹配。

Unicode 注意事项

如果您需要检查任何 Unicode 大写字母,请使用\p{Lu} 而不是[A-Z]

return input.range(of: "\\p{Lu}", options: .regularExpression) != nil

或者,如果您需要使用NSPredicate 版本:

let upperCaseRegex = "(?s)\\P{Lu}*\\p{Lu}.*"

请注意,\P{Lu}* 匹配 0+ 个字符而不是大写字母。

【讨论】:

  • 最后我用了:"^(.*[A-Z]+.*"
  • @user3239711:在 NSPredicate 中,您可以使用 .*[A-Z].*。但它的效率低于[^A-Z]*[A-Z].*。好吧,如果你确定字符串没有换行符并且很短,.*[A-Z].* 就可以了。
【解决方案2】:

如果您不检查大写字母的任何特定位置,那么[A-Z] 将起作用。例如,在 javascript 中,我会使用 /[A-Z]/.test("fRed") 并获得 true 并且 /[A-Z]/.test("fred") 返回 false。

【讨论】:

    【解决方案3】:

    用途:

    [A-Z]+
    
    • [A-Z]: A (ASCII 65) 到 Z 范围内的单个字符 (ASCII 90)(区分大小写)。
    • + 量词 - 匹配一次到无限次,尽可能多 尽可能多地回馈(贪婪)。

    Live demo 中查看它。

    【讨论】:

    • 请注意,在 Javascript 中,这是一个无限的正则表达式。所以我不会真正使用它。
    • 但是这个问题没有被标记为 JS,但是我有兴趣 @KarlReid 来改进我的答案。你有什么建议?
    • 老实说,我只会使用[A-Z]+!如果只需要测试是否有大写字母,似乎就可以了。我应该澄清一下,你的正则表达式并没有什么问题,它只是需要一点小心。如果你在Javascript中使用g标志并重复调用exec,这是一个无限循环,AFAIU
    • 谢谢@KarlReid,我更新了我的答案,你觉得现在怎么样?
    • 没关系,但你不需要因为我发表的评论而完全改变它,我不是专家,我可能完全错了..发布一个你自己有信心的答案在:)
    猜你喜欢
    • 1970-01-01
    • 2012-06-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-26
    • 1970-01-01
    • 2016-12-14
    • 2013-02-14
    相关资源
    最近更新 更多