Make sure regex matches the entire string with Swift regex

后端 未结 3 1000
萌比男神i
萌比男神i 2020-12-04 01:39

How to check whether a WHOLE string can be matches to regex? In Java is method String.matches(regex)

相关标签:
3条回答
  • 2020-12-04 02:15

    Swift extract regex matches

    with little bit of edit

    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
        }
    }
    

    Example usage from link above:

    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
    
    0 讨论(0)
  • 2020-12-04 02:29

    What you are looking for is range(of:options:range:locale:) then you can then compare the result of range(of:option:) with whole range of comparing string..

    Example:

    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
    

    Edit: You can also use NSPredicate and compare your string with evaluate(with:) method of its.

    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")
    }
    
    0 讨论(0)
  • 2020-12-04 02:41

    You need to use anchors, ^ (start of string anchor) and $ (end of string anchor), with range(of:options:range:locale:), passing the .regularExpression option:

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

    Or, you may pass an array of options, [.regularExpression, .anchored], where .anchored will anchor the pattern at the start of the string only, and you will be able to omit ^, but still, $ will be required to anchor at the string end:

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

    See the online Swift demo

    Also, using NSPredicate with MATCHES is an alternative here:

    The left hand expression equals the right hand expression using a regex-style comparison according to ICU v3 (for more details see the ICU User Guide for Regular Expressions).

    MATCHES actually anchors the regex match both at the start and end of the string (note this might not work in all Swift 3 builds):

    let pattern = "\\d{3}-\\d{3}-\\d{3}"
    let predicate = NSPredicate(format: "self MATCHES [c] %@", pattern)
    let result = predicate.evaluate(with: "123-456-789") 
    
    0 讨论(0)
提交回复
热议问题