如何使用Swift创建日期正则表达式?

时间:2019-04-20 19:41:37

标签: ios swift regex rx-swift

我正在尝试为this之类的日期创建一个正则表达式字符串。我的代码(Swift 5示例):

let dateValidator = TextValidator(input: dateTextField.rx.text.asObservable(), regex: try! NSRegularExpression(pattern:
    #"^\s*(3[01]|[12][0-9]|0?[1-9])\.(1[012]|0?[1-9])\.((?:19|20)\d{2})\s*$"#))

let v = Observable.combineLatest(dateValidator.validate(), anotherValidator.validate()) {
    (date, another) in
    return date && another
}
//another code

class TextValidator {
    var input: Observable<String?>
    var regex: NSRegularExpression

    init(input: Observable<String?>, regex: NSRegularExpression) {
        self.input = input
        self.regex = regex
    }

    func validate() -> Observable<Bool> {
        return input.map { text in
            let range = NSRange(location: 0, length: text!.utf8.count)
            return self.regex.firstMatch(in: text!, options: [], range: range) != nil
        }
    }
}

我收到错误消息:

  

由于未捕获的异常“ NSRangeException”而终止应用程序,原因:   '***-[NSRegularExpression   enumerateMatchesInString:options:range:usingBlock:]:范围或索引   越界'

另一个正则表达式可以正常工作。我认为正则表达式中反斜杠的错误。

1 个答案:

答案 0 :(得分:1)

获取Swift NSRange的{​​{1}}时,您想使用String而不是utf16

utf8

个人而言,我发现选择func validate() -> Observable<Bool> { return input.map { text in guard let text = text else { return false } let range = NSRange(location: 0, length: text.utf16.count) return self.regex.firstMatch(in: text, range: range) != nil } } utf8之间的逻辑是不必要的不​​透明,我使用了utf16初始化程序:

NSRange(_:in:)

可以这么说,在构建func validate() -> Observable<Bool> { return input.map { text in guard let text = text else { return false } let range = NSRange(text.startRange..., in: text) return self.regex.firstMatch(in: text, range: range) != nil } } 时使用utf8.count只会在字符串中包含非ASCII字符的情况下表明崩溃。这可能可以解释为什么当您使用NSRange修复此问题时,为什么崩溃消失了,但验证仍然失败。字符串必须包含扩展的Unicode字符,因此,根据定义,它们不符合正则表达式。