Raim Khalil
Raim Khalil

Reputation: 387

Regex application to string?

Currently, I am looping through phone numbers to find matches in a database. However, I need to remove dashes and any area codes so that the database search can exact. Currently, I am trying to use this regex on the phone numbers :

(?:\+\d{2}\s*(?:\(\d{2}\))|(?:\(\d{2}\)))?\s*(\d{4,5}\-?\d{4})

and I am trying to apply it as such

       if let longNumber = (contact.phoneNumbers.first?.value as? CNPhoneNumber)?.stringValue  {
                    let phoneNumber = longNumber.replacingOccurrences(of: "(?:\+\d{2}\s*(?:\(\d{2}\))|(?:\(\d{2}\)))?\s*(\d{4,5}\-?\d{4})", with: "$1", options: .regularExpression)

However, I receive the error Invalid escape sequence in literal and Missing argument for parameter 'for' in call

How can I properly get only the phone digits from the string? ie if it is +1 300-300-3000

I need it to return 3003003000.

Examples:

+1 390 - 456 - 8823 -> 3904568823

+92 084 765 4902 --> 0847654902

+922 (064) 864 0921 --> 0648640921

842.231.9072 --> 8422319072

+1 (972) - 864 - 0921 --> 9728640921

+92 33 - 783 - 9382 --> 337839282

Upvotes: 0

Views: 65

Answers (1)

OOPer
OOPer

Reputation: 47886

From the examples you have shown, I assume the following rules:

Phone numbers are formatted in 3 or 4 parts

Part1 (optional)

  • +
  • 1 to 3 digits
  • one or more whitespaces follow

Part2

  • May be enclosed in ( and )
  • 2 or 3 digits
  • a hyphen or a decimal point or a whitespace with extra whitespaces at both ends follows

Part3

  • 3 digits
  • a hyphen or a decimal point or a whitespace with extra whitespaces at both ends follows

Part4

  • 4 digits

(Please remember, this sort of phone number notation rule is local to a specific region. When you want to internationalize your app, you may need many more rules. The pattern you have now may be written for some other region.)

Partial pattern for each part would be something as follows:

let part1 = "(?:\\+\\d{1,3}\\s+)?"
let part2 = "(?:\\((\\d{2,3})\\)|(\\d{2,3}))\\s*[\\s\\.-]?\\s*"
let part3 = "(\\d{3})\\s*[\\s\\.-]?\\s*"
let part4 = "(\\d{4})"

(Please do not miss that all backslashes are escaped.)

Testing code:

import Foundation

let numbers: [(long: String, expected: String)] = [
    ("+1 300-300-3000",       "3003003000"),
    ("+1 390 - 456 - 8823",   "3904568823"),
    ("+92 084 765 4902",      "0847654902"),
    ("+922 (064) 864 0921",   "0648640921"),
    ("842.231.9072",          "8422319072"),
    ("+1 (972) - 864 - 0921", "9728640921"),
    ("+92 33 - 783 - 9382",   "337839382"),   //I assume your example is wrong here
]
for number in numbers {
    let longNumber = number.long
    let part1 = "(?:\\+\\d{1,3}\\s+)?"
    let part2 = "(?:\\((\\d{2,3})\\)|(\\d{2,3}))\\s*[\\s\\.-]?\\s*"
    let part3 = "(\\d{3})\\s*[\\s\\.-]?\\s*"
    let part4 = "(\\d{4})"
    let pattern = "^\(part1)\(part2)\(part3)\(part4)$"
    let phoneNumber = longNumber.replacingOccurrences(of: pattern, with: "$1$2$3$4", options: .regularExpression)
    print("\(longNumber) --> \(phoneNumber)", phoneNumber == number.expected ? "Success" : "Fail (expected \(number.expected))")
}

Output:

+1 300-300-3000 --> 3003003000 Success
+1 390 - 456 - 8823 --> 3904568823 Success
+92 084 765 4902 --> 0847654902 Success
+922 (064) 864 0921 --> 0648640921 Success
842.231.9072 --> 8422319072 Success
+1 (972) - 864 - 0921 --> 9728640921 Success
+92 33 - 783 - 9382 --> 337839382 Success

The code above may not work as expected for possible other inputs, please try to fix it to fit for such inputs by yourself.

Upvotes: 1

Related Questions