Guillaume
Guillaume

Reputation: 1720

Regular expression in Swift not working fully

I need to use NSRegularExpression in my Swift application to check if latitude and longitude coordinates informed by user is in correct format.

My regular expression: -?[0-9]{1,3}[.]{1}[0-9]{6}

This regular expression work but not fully. It make to:

  1. The coordinate can begin by -
  2. The coordinate can then begin by 3 maximum numbers
  3. Then the characters . is necessary
  4. And to finish 6 numbers are necessary but not more

The problems are:

  1. If I begin by every characters, the expression return true: ?.-33.476543
  2. If then I paste more of 3 numbers the expression return true: -33555.476543
  3. And if I paste more of 6 numbers after the . the expression return true: -33.476543546565565765

It's normal but how can I create a "patern" to force user to informed only 6 numbers or only begin by -character for exemple?

The regular expression in code:

let regex = NSRegularExpression("-?[0-9]{1,3}[.]{1}[0-9]{6}")
  if regex.matches(self.latitude) && regex.matches(self.longitude) {
    self.coordinatesValid = true
  } else {
    self.coordinatesValid = false
}

My NSRegularExpression extension:

import Foundation

extension NSRegularExpression {
  convenience init(_ pattern: String) {
    do {
      try self.init(pattern: pattern)
    } catch {
      preconditionFailure("Illegal regular expression: \(pattern).")
    }
  }

  func matches(_ string: String) -> Bool {
    let range = NSRange(location: 0, length: string.utf16.count)
    return firstMatch(in: string, options: [], range: range) != nil
  }
}

Upvotes: 1

Views: 910

Answers (2)

Alvaro Royo
Alvaro Royo

Reputation: 156

I use this string extension for RexExp:

extension String {
    func match(_ regularExpression: String) -> Bool {
        return self.range(of: regularExpression, options: .regularExpression) != nil
    }
}

Swift 5 have added literal strings. This is perfect to use with regular expressions.

You could write regular expressions without scape the string like this:

#"([\w!#$%&'*+/=?`{|}~^-])+(?:\.[\w!#$%&'*+/=?`{|}~^-]+)*@[A-Za-z0-9.-]+\.[A-Za-z]{2,64}"#

Note that your string become with # that means that is a literal string and with this kind of string if you write for example \n that not mean a brake line.

Upvotes: 0

ielyamani
ielyamani

Reputation: 18591

You can try this:

"^-?[0-9]{1,3}[.]{1}[0-9]{6}$"

With:

  • ^ : Start of a string
  • $ : End of a string

Here are some test cases:

let latitudes = ["?.-33.476543", 
                 "-33555.476543",
                 "-33.476543546565565765",
                 "abc-333.476543xyz",
                 "-333.476543",
]

let regex = NSRegularExpression("^-?[0-9]{1,3}[.]{1}[0-9]{6}$")

for latitude in latitudes {
    print(regex.matches(latitude), "\t", latitude)
}

Here is the output:

false    ?.-33.476543
false    -33555.476543
false    -33.476543546565565765
false    abc-333.476543xyz
true     -333.476543

Upvotes: 1

Related Questions