0

I'm trying to build a regex to match a specific format. The regex is this :

let regex = NSRegularExpression.init(#"[A-Z]{2}: (\d*(.?\d{1,2})?)\\|$"#)

I wrote it using regexr.com, using this format : [A-Z]{2}\:\s(\d*(\.?\d{1,2})?)\|$. I show you how it should work :

"AL: 90|" fine
"AL: 8.2|" fine
"AL" wrong
"AL: 8" wrong

Hope I gave you the idea.

Now, here's the extension I'm using.

extension NSRegularExpression {

    convenience init(_ pattern: String) {

        do {
            try self.init(pattern: pattern)
        } catch {
            preconditionFailure("Illegal regular expression: \(pattern).")
        }
    }
}


// MARK: - Matches

extension NSRegularExpression {

    func matches(_ string: String) -> Bool {

        let range = NSRange(location: 0, length: string.utf16.count)

        return firstMatch(in: string, options: [], range: range) != nil
    }
}

This is the code :

let regex = NSRegularExpression.init(#"[A-Z]{2}: (\d*(.?\d{1,2})?)\\|$"#)

if regex.matches(message.text) {
    print("Matches!")
} else {
    print("Text not valid!")
}

And it's not working. It gives me these results :

"al" matches
"aAl" matches
"AL: 9" matches

I really cannot understand what's wrong with my regex as on regexr works fine.

Andrea Mario Lufino
  • 7,921
  • 12
  • 47
  • 78
  • @WiktorStribiżew but it's a raw string, should I do it also in this case? – Andrea Mario Lufino Mar 12 '20 at 21:10
  • You should add `^` at the start of ghe pattern to enforce a full string match. And use ``\|`` to match a literal ``|``. All backslashes are literal in a raw string literal, so it is a mistake to double it before a literal pipe. – Wiktor Stribiżew Mar 12 '20 at 21:15
  • 1
    In plain English: if you wrote a pattern in an online regex tester, when using a raw string literal, just paste it there as is, do not modify the backslashes – Wiktor Stribiżew Mar 12 '20 at 21:24
  • @WiktorStribiżew I pasted it exactly the same as I wrote in the online tester, but nothing to do. It doesn't match the string, even if it should match it. I do not know if it's something related to my extension of `NSRegularExpression` maybe. – Andrea Mario Lufino Mar 13 '20 at 07:48
  • Note you also need to escape `.` since you expect a float number there. With `let regex = NSRegularExpression.init(#"[A-Z]{2}: (\d*(\.?\d{1,2})?)\|$"#)`, `AL:` results in `Text not valid!`. Are you sure you pass the right values in `message.text`? Anyway, the issue is not repro after fixing the backslash before `|`. – Wiktor Stribiżew Mar 13 '20 at 07:58
  • @WiktorStribiżew This is the regex I'm using : `let regex = NSRegularExpression.init(#"^[A-Z]{2}\: (\d*(\.?\d{1,2})?)\|$"#)`. It should be correct, it is exactly the copy of the one I have on regexr. If I pass `AL: 8|` results in `Text not valid!`. – Andrea Mario Lufino Mar 13 '20 at 08:25
  • With that line of code, `AL: 9` => *Text not valid!*, `AL: 8|` => *Matches!*. Try yourself at http://online.swiftplayground.run/. Swift 5.1-RELEASE. – Wiktor Stribiżew Mar 13 '20 at 08:27

0 Answers0