【问题标题】:Make sure regex matches the entire string with Swift regex确保正则表达式与 Swift 正则表达式匹配整个字符串
【发布时间】:2017-09-26 07:59:02
【问题描述】:

如何检查整个字符串是否可以匹配正则表达式?在 Java 中是方法 String.matches(regex)

【问题讨论】:

  • 结果是否只需要一个布尔值?
  • 是的,我只需要一个布尔结果
  • 好吧,我怀疑它有一个特定的方法,你不能在你的模式中使用^$ 锚点吗?我的意思是,你定义模式还是用户定义的?
  • 我已经定义了一个模式,并检查用户在 TextField 中引入的文本是否与模式匹配
  • 好的,你只需要使用^$ 来定义开始和结束位置。有.anchored 选项,但它在PHP 中作为/A 工作,仅锚定在字符串的开头。

标签: regex swift


【解决方案1】:

您需要使用锚点,^(字符串锚点的开始)和$(字符串锚点的结束),以及range(of:options:range:locale:),传递.regularExpression 选项:

import Foundation

let phoneNumber = "123-456-789"
let result = phoneNumber.range(of: "^\\d{3}-\\d{3}-\\d{3}$", options: .regularExpression) != nil
print(result)

或者,您可以传递一个选项数组[.regularExpression, .anchored],其中.anchored 将仅将模式锚定在字符串的开头,您可以省略^,但仍然可以省略$将需要在字符串末尾锚定:

let result = phoneNumber.range(of: "\\d{3}-\\d{3}-\\d{3}$", options: [.regularExpression, .anchored]) != nil

online Swift demo

另外,在这里使用NSPredicateMATCHES 是另一种选择:

根据 ICU v3,左侧表达式使用正则表达式样式比较等于右侧表达式(有关更多详细信息,请参阅Regular Expressions 的 ICU 用户指南)。

MATCHES 实际上将正则表达式匹配锚定在字符串的开头和结尾请注意,这可能不适用于所有 Swift 3 版本):

let pattern = "\\d{3}-\\d{3}-\\d{3}"
let predicate = NSPredicate(format: "self MATCHES [c] %@", pattern)
let result = predicate.evaluate(with: "123-456-789") 

【讨论】:

    【解决方案2】:

    您要查找的是range(of:options:range:locale:),然后您可以将 range(of:option:) 的结果与整个比较字符串范围进行比较..

    示例:

    let phoneNumber = "(999) 555-1111"
    let wholeRange = phoneNumber.startIndex..<phoneNumber.endIndex
    if let match = phoneNumber.range(of: "\\(?\\d{3}\\)?\\s\\d{3}-\\d{4}", options: .regularExpression), wholeRange == match {
        print("Valid number")
    }
    else {
        print("Invalid number")
    }
    //Valid number
    

    编辑:您还可以使用NSPredicate 并将您的字符串与其evaluate(with:) 方法进行比较。

    let pattern = "^\\(?\\d{3}\\)?\\s\\d{3}-\\d{4}$"
    let predicate = NSPredicate(format: "self MATCHES [c] %@", pattern)
    if predicate.evaluate(with: "(888) 555-1111") {
        print("Valid")
    }
    else {
        print("Invalid")
    }
    

    【讨论】:

    • 我认为"\\(?\\d{3}\\)?\\s\\d{3}-\\d{4}" 也将允许部分匹配。在图案两侧添加^$ 锚点。
    • @WiktorStribiżew 编辑答案
    • 是的,我也想过。我认为还有另一种方法,但找不到让 NSPredicate 在 Swift 3 中工作的方法。很不幸.anchored 只在字符串开头锚定。
    • @WiktorStribiżew 谢谢你提醒我NSPredicate,也编辑了答案
    • 不,不是the only issue。 Mabe NSPredicate 在 Swift 3.0.2 中还没有准备好。
    【解决方案3】:

    Swift extract regex matches

    稍加修改

    import Foundation
    
    func matches(for regex: String, in text: String) -> Bool {
        do {
            let regex = try NSRegularExpression(pattern: regex)
            let nsString = text as NSString
            let results = regex.matches(in: text, range: NSRange(location: 0, length: nsString.length))
            return !results.isEmpty
        } catch let error {
            print("invalid regex: \(error.localizedDescription)")
            return false
        }
    }
    

    以上链接的用法示例:

    let string = "19320"
    let matched = matches(for: "^[1-9]\\d*$", in: string)
    print(matched) // will match
    
    let string = "a19320"
    let matched = matches(for: "^[1-9]\\d*$", in: string)
    print(matched) // will not match
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-09-19
      • 1970-01-01
      • 1970-01-01
      • 2015-06-29
      • 1970-01-01
      相关资源
      最近更新 更多