📜 ⬆️ ⬇️

MSLibrary. Capturing and verifying phone numbers using regular expressions, for iOS and not only ... Part 2

In the first part of the article, the developers of the MSLibrary for iOS library told about the features of the structure of telephone numbers from the point of view of international standards published in RFC 3966 , reviewed the International structure of telephone numbers, corporate WEB standards for dialing a telephone number, their interaction with each other and how they behave users.
As already mentioned, capture and verification are different tasks, but they are solved by similar methods, differing mainly by regular expressions used in them. In the second part of the article we will talk about regular expressions.

Phone number verification

There are several possible approaches to the formulation of the task of verifying or validating a line of a telephone number.
1. choose one of the most simple variant of writing a valid number and construct a regular expression for it
2. consider the largest possible number of valid spellings of telephone numbers and construct a regular expression for them
')
Both approaches have the right to exist, but each of them entails certain consequences.
In the first case, either the user will have to enter the number in the form in which the verification is performed, which often leads to errors and, as a result, to a negative attitude towards the application. Either the developer will need to create a template for data entry or additional code that leads the entered data to the selected valid form.
In the second case, you can do without a template and an additional code, limiting yourself with a small instruction like “enter the phone number without spaces”.

Consider both options, but first general considerations.

Validating the phone number string so that it is adequately processed by iOS comes down to several conditions:
1. The general structure of the number should be in accordance with RFC 3966.

telephone-uri = global-number-digits [extension] 
rice one

2. The telephone number must always begin and end with a digit.

3. the structure of the global-number-digits must comply with RFC 3966 subject to paragraph 2 ( see the first part of the article )
  global-number-digits = "+" * DIGIT * phonedigit DIGIT 

4. the number of numeric characters in the global-number-digits must be in the range of 11-13 digits (this condition follows from the International structure of telephone numbers)

5. The structure of the optional element - the extension number [extension] should be different from that proposed in RFC 3966
  extension = (";" | * ",") 1 * (DIGIT * phonedigit DIGIT) 

Substituting the corresponding values ​​into the scheme shown in Figure 1, we obtain a more detailed structure of the phone number valid for iOS:

 telephone-uri = "+" DIGIT (9-11)*phonedigit DIGIT [(";" | *",") DIGIT *phonedigit DIGIT] 
rice 2

And only now, having made sure that the structure obtained (Fig. 2) satisfies the task and international agreements, one can proceed to the construction of regular expressions.

For clarity, let's start with regular expressions for each of the parts of the structure shown in Fig. 2

Digit
  REGEX [0-9]
 REGEX_OBJC_STRING @ "\\ d" 

phonedigit
  REGEX [0-9] | [- \. \ (\)]
 REGEX_OBJC_STRING @ "\\ d | [- \\. \\ (\\)]" 

We proceed to constructing a regular expression for the first variant. Choose one, the simplest, writing a valid phone number for iOS systems, for example
 +14089961010; 1234

The regular expression that describes the structure of this phone number is as follows:
  REGEX ^ ((?: \ +? [0-9] {11,13}) (? :(; |, +) [0-9] +)?) $ 

Let us examine this expression:
 ^ (# beginning of line
 (?: # start of the global-number-digits block
 \ +?  # sign "+" (you can use no more than once)
 [0-9] # segment DIGIT global-number-digits block
 {11,13} # pointer to the fact that the segment DIGIT is possible from 11 to 13 times
 ) # end of the block global-number-digits
 (?: # start of extension block
 (; |, +) # separator, indicating the beginning of the extension number
 [0-9] + # segment DIGIT block extension
 )?  # end block extension
 ) $ # end of line


So, for the first of the options considered, the following regular expression can be used to validate the phone number before using it in the iOS application code:

  REGEX_OBJC_STRING @ "^ ((?: \\ +? \\ d {11,13}) (? :(; |, +) \\ d +)?) $" 

For the second option, valid for iOS systems, a phone number that fully satisfies the structure shown in Figure. 2, a regular expression, looks like this:
  REGEX ^ ((?: \ +? [0-9] ([-. \ (\)]? [0-9]) {10,12}) (? :(; |, +) ([0-9 ] ([-. \ (\)]? [0-9])?) +)?) $ 

Let us examine this expression:
 ^ (# beginning of line
 (?: # start of the global-number-digits block
 \ +?  # sign "+" (you can use no more than once)
 [0-9] # the first segment of the DIGIT global-number-digits block
 (# the beginning of the phonedigit segment of the global-number-digits block
 [-. \ (\)]?  # visual separator (can be used no more than once in this segment)
 [0-9] # second segment of DIGIT global-number-digits block
 ) # ending the phonedigit segment of the global-number-digits block
 {10,12} # pointer to the fact that the phonedigit segment is possible 10 to 12 times
 ) # end of the block global-number-digits
 (?: # start of extension block
 (; |, +) # separator, indicating the beginning of the extension number
 (# the beginning of the digital part of the block extension
 [0-9] # first segment DIGIT block extension
 (#beginning of phonedigit block extension
 [-. \ (\)]?  # visual separator (can be used no more than once in this segment)
 [0-9] # second segment DIGIT block extension
 )?  # end of phonedigit block extension
 ) + # end of the digital part of the block extension
 )?  # end block extension
 ) $ # end of line


So, for the second of the options considered, the following regular expression can be used to validate the phone number before using it in the iOS application code:

  REGEX_OBJC_STRING @ "^ ((?: \\ +? \\ d ([-. \\ (\\)]? \\ d) {10,12})) (? :(; |, +) (\\ d ([-. \\ (\\)]? \\ d)?) +)?) $ " 


Capturing phone numbers

Capture is the definition that a set of digits and characters to be tracked can be a telephone number. When constructing a regular expression for capturing a phone number, it should be taken into account that in the analyzed line:
1. must contain all the elements necessary for successful verification of the phone number in the required sequence

2. may contain foreign elements

3. Valid separators may be replaced with invalid ones.

The second and third paragraphs should be discussed in more detail. Let's try to understand the very vague concepts of "foreign" and "non-valid" elements.

As visual separators, besides those discussed above, when manually typing, a space (whitespace) is often used. A space can be used both as an invalid separator and as a foreign element, if it stands before or after the separator.
For, designation of the beginning of the extension number, the following non-valid separators can be used:
  "x" |  "ext" |  ":" |  "p" |  "=" 


In view of the above, the regular expression for phonedigit and the separator denoting the beginning of the extension number will take the following form:
phonedigit
  REGEX [0-9] | (\ s? [- \. \ (\) \ S] \ s?)
 REGEX_OBJC_STRING @ "[0-9] | (\\ s? [- \\. \\ (\\) \\ s] \\ s?)" 

extension separator
  REGEX (x | ext | p |; | = |, +)
 REGEX_OBJC_STRING @ "(x | ext | p |; | = |, +)" 


A regular expression that satisfies the conditions is as follows:
  REGEX ^ (\ s? (?: (\ +? \ S? [0-9] ((\ s? [- \. \ (\) \ S] \ s?)? [0-9]) {10 , 12})) (?: ((X | ext | p |; | = |, +) (\ s? [0-9] ((\ s? [- \. \ (\) \ S] \ s ?)? [0-9])?) +)?) $ 

Let us examine this expression:
 ^ (# beginning of line
 \ s?  # space allowed at the beginning of a line
 (? :( # start of the global-number-digits block
 \ +?  # sign "+" (you can use no more than once)
 \ s?  # space allowed after "+"
 [0-9] # the first segment of the DIGIT global-number-digits block
 (# the beginning of the phonedigit segment of the global-number-digits block
 (\ s? [- \. \ (\) \ s] \ s?)?  # visual separator (can be used no more than once in this segment)
 [0-9] # second segment of DIGIT global-number-digits block
 ) # ending the phonedigit segment of the global-number-digits block
 {10,12} # pointer to the fact that the phonedigit segment is possible 10 to 12 times
 )) # end of the block global-number-digits
 (? :( # start of block extension
 (x | ext | p |; | = |, +) # separator, indicating the beginning of the extension number
 (# the beginning of the digital part of the block extension
 \ s?  #space allowed at the beginning of the digital part of the extension block
 [0-9] # first segment DIGIT block extension
 (#beginning of phonedigit block extension
 (\ s? [- \. \ (\) \ s] \ s?)?  # visual separator (can be used no more than once in this segment)
 [0-9] # second segment DIGIT block extension
 )?  # end of phonedigit block extension
 ) + # end of the digital part of the block extension
 )?  # end block extension
 ) $ # end of line


So, to capture a phone number that meets the set conditions, you can use the following regular expression:

  REGEX_OBJC_STRING @ "^ (\\ s? (?: (\\ +? \\ s? \\ d ((\\ s? [- \\. \\ (\\) \ s] \\ s?)? \\ d) {10,12})) (?: ((x | ext | p |; | = |, +) (\\ s? \\ d ((\\ s? [- \\. \\ (\\) \\ s] \\ s?)? \\ d)?) +)?) $ " 

In order to use the phone number captured in this way, it is necessary to make its rationing, that is, to bring the string to a valid one for use in iOS. The description of the rationing technology is beyond the scope of this article. You can only say that in the MSLibrary for iOS library this problem is solved using a single function.

Let's sum up

The task of verifying or validating a phone number string is solved using one of the following regular expressions:
  REGEX_OBJC_STRING @ "^ ((?: \\ +? \\ d {11,13}) (? :(; |, +) \\ d +)?) $" 

  REGEX_OBJC_STRING @ "^ ((?: \\ +? \\ d ([-. \\ (\\)]? \\ d) {10,12})) (? :(; |, +) (\\ d ([-. \\ (\\)]? \\ d)?) +)?) $ " 

The task of capturing a string containing a phone number can be solved using the following regular expression:
  REGEX_OBJC_STRING @ "^ (\\ s? (?: (\\ +? \\ s? \\ d ((\\ s? [- \\. \\ (\\) \ s] \\ s?)? \\ d) {10,12})) (?: ((x | ext | p |; | = |, +) (\\ s? \\ d ((\\ s? [- \\. \\ (\\) \\ s] \\ s?)? \\ d)?) +)?) $ " 

You can use the received regular expressions when developing iOS applications using the methods of the NSRegularExpression class.

The MSLibrary for iOS library also has its own tools for this. For example, the msfFRMreqMatchesInString function

 BOOL msfFRMreqMatchesInString(NSString *string, NSString *regularExpression, NSInteger reqNumberOfMatches) 
rice 3

This function takes the value YES or NO, depending on whether the string “string” matches the regular expression “regularExpression” a certain number of times - “reqNumberOfMatches”. As you can see the issue is solved in just one line of code.
In addition, the library has several dozen carefully selected regular expressions “for all occasions”.




We hope that the material was useful to you, the MSLibrary for iOS team

Other articles:
Capture and verify phone numbers using regular expressions, for iOS and not only ... Part 1
Implementing multiple selection of conditions using bitmasks, for iOS and not only ...
SIMPLE: remove unnecessary characters from the string, for iOS and not only ...
Creating and compiling cross-platform (universal) libraries in Xcode

Source: https://habr.com/ru/post/278359/


All Articles