Search code examples
iosswiftnspredicate

Why am i getting this error while using Regex string from a .plist file?


When i am obtaining regex stored in a .plist file and supplying it to NSPredicate it is giving me an error. What basic concept of programming i am missing here ?

Previously i was using a regex like the following

static let PASSWORD_REGEX: String = "^[a-zA-Z_0-9\\-#!$@~`%&*()_+=|\"\':;?/>.<,]{6,15}$"

And supplying it for pattern match like this. and it was working fine.

func isValidPassword() -> Bool {

    let passwordRegex = Constants.PASSWORD_REGEX
    let passwordTest = NSPredicate(format: "SELF MATCHES %@", passwordRegex)
    let rVal = passwordTest.evaluate(with: self)
    return rVal
}

What have i changed is, i have moved this regex string to a .plist file and i am obtaining it from there. :-

static let PASSWORD_REGEX: String = Constants.getCustomizableParameter(forKey: "PASSWORD_REGEX")

static func getCustomizableParameter(forKey: String) -> String {
    var customizableParameters: NSDictionary?
    if let customizableParametersPlistPath = Bundle.main.path(forResource: "CustomizableParameters", ofType: "plist") {
        customizableParameters = NSDictionary(contentsOfFile: customizableParametersPlistPath)
    }
    if customizableParameters != nil {
        return customizableParameters![forKey] as! String
    } else {
        return ""
    }
}

And values in my plist are as follows :- enter image description here

Now when i am using the same password validation function. it is giving me following error :-

Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Can't do regex matching, reason: Can't open pattern U_REGEX_INVALID_RANGE (string asdasd, pattern ^[a-zA-Z_0-9\\-#!$@~`%&*()_+=|\"\':;?/>.<,]{6,15}$, case 0, canon 0)'

Solution

  • In a literal string in code you have to escape characters (e.g. \" instead of simple ").

    In plist there is no such need. The \ characters will stay there, making your pattern invalid.

    Remove the additional \ chars and everything will start to work.

    Compare:

    let PASSWORD_REGEX: String = "^[a-zA-Z_0-9\\-#!$@~`%&*()_+=|\"\':;?/>.<,]{6,15}$"
    print(PASSWORD_REGEX)
    

    outputs:

    ^[a-zA-Z_0-9\-#!$@~`%&*()_+=|"':;?/>.<,]{6,15}$
    

    Which is the correct regular expression