@@ -206,7 +206,7 @@ class Leniency(object):
206206 EXACT_GROUPING = 3
207207
208208
209- def _verify (leniency , numobj , candidate ):
209+ def _verify (leniency , numobj , candidate , matcher ):
210210 """Returns True if number is a verified number according to the
211211 leniency."""
212212 if leniency == Leniency .POSSIBLE :
@@ -217,21 +217,21 @@ def _verify(leniency, numobj, candidate):
217217 return False
218218 return _is_national_prefix_present_if_required (numobj )
219219 elif leniency == Leniency .STRICT_GROUPING :
220- return _verify_strict_grouping (numobj , candidate )
220+ return _verify_strict_grouping (numobj , candidate , matcher )
221221 elif leniency == Leniency .EXACT_GROUPING :
222- return _verify_exact_grouping (numobj , candidate )
222+ return _verify_exact_grouping (numobj , candidate , matcher )
223223 else :
224224 raise Exception ("Error: unsupported Leniency value %s" % leniency )
225225
226226
227- def _verify_strict_grouping (numobj , candidate ):
227+ def _verify_strict_grouping (numobj , candidate , matcher ):
228228 if (not is_valid_number (numobj ) or
229229 not _contains_only_valid_x_chars (numobj , candidate ) or
230230 _contains_more_than_one_slash_in_national_number (numobj , candidate ) or
231231 not _is_national_prefix_present_if_required (numobj )):
232232 return False
233- return _check_number_grouping_is_valid (numobj , candidate ,
234- _all_number_groups_remain_grouped )
233+ return matcher . _check_number_grouping_is_valid (numobj , candidate ,
234+ _all_number_groups_remain_grouped )
235235
236236
237237def _all_number_groups_remain_grouped (numobj , normalized_candidate , formatted_number_groups ):
@@ -284,14 +284,14 @@ def _all_number_groups_remain_grouped(numobj, normalized_candidate, formatted_nu
284284 return (normalized_candidate [from_index :].find (numobj .extension or U_EMPTY_STRING ) != - 1 )
285285
286286
287- def _verify_exact_grouping (numobj , candidate ):
287+ def _verify_exact_grouping (numobj , candidate , matcher ):
288288 if (not is_valid_number (numobj ) or
289289 not _contains_only_valid_x_chars (numobj , candidate ) or
290290 _contains_more_than_one_slash_in_national_number (numobj , candidate ) or
291291 not _is_national_prefix_present_if_required (numobj )):
292292 return False
293- return _check_number_grouping_is_valid (numobj , candidate ,
294- _all_number_groups_are_exactly_present )
293+ return matcher . _check_number_grouping_is_valid (numobj , candidate ,
294+ _all_number_groups_are_exactly_present )
295295
296296
297297def _all_number_groups_are_exactly_present (numobj , normalized_candidate , formatted_number_groups ):
@@ -334,43 +334,32 @@ def _all_number_groups_are_exactly_present(numobj, normalized_candidate, formatt
334334 candidate_groups [candidate_number_group_index ].endswith (formatted_number_groups [0 ]))
335335
336336
337- def _get_national_number_groups (numobj , formatting_pattern = None ):
337+ def _get_national_number_groups_without_pattern (numobj ):
338338 """Helper method to get the national-number part of a number, formatted without any national
339- prefix, and return it as a set of digit blocks that would be formatted together."""
340- if formatting_pattern is None :
341- # This will be in the format +CC-DG;ext=EXT where DG represents groups of digits.
342- rfc3966_format = format_number (numobj , PhoneNumberFormat .RFC3966 )
343- # We remove the extension part from the formatted string before splitting
344- # it into different groups.
345- end_index = rfc3966_format .find (U_SEMICOLON )
346- if end_index < 0 :
347- end_index = len (rfc3966_format )
348-
349- # The country-code will have a '-' following it.
350- start_index = rfc3966_format .find (U_DASH ) + 1
351- return rfc3966_format [start_index :end_index ].split (U_DASH )
352- else :
353- # We format the NSN only, and split that according to the separator.
354- nsn = national_significant_number (numobj )
355- return _format_nsn_using_pattern (nsn , formatting_pattern ,
356- PhoneNumberFormat .RFC3966 ).split (U_DASH )
357-
358-
359- def _check_number_grouping_is_valid (numobj , candidate , checker ):
360- # TODO: Evaluate how this works for other locales (testing has been
361- # limited to NANPA regions) and optimise if necessary.
362- normalized_candidate = normalize_digits_only (candidate , True ) # keep non-digits
363- formatted_number_groups = _get_national_number_groups (numobj , None )
364- if checker (numobj , normalized_candidate , formatted_number_groups ):
365- return True
366- # If this didn't pass, see if there are any alternate formats, and try them instead.
367- alternate_formats = _ALT_NUMBER_FORMATS .get (numobj .country_code , None )
368- if alternate_formats is not None :
369- for alternate_format in alternate_formats :
370- formatted_number_groups = _get_national_number_groups (numobj , alternate_format )
371- if checker (numobj , normalized_candidate , formatted_number_groups ):
372- return True
373- return False
339+ prefix, and return it as a set of digit blocks that would be formatted together following
340+ standard formatting rules."""
341+ # This will be in the format +CC-DG1-DG2-DGX;ext=EXT where DG1..DGX represents groups of
342+ # digits.
343+ rfc3966_format = format_number (numobj , PhoneNumberFormat .RFC3966 )
344+ # We remove the extension part from the formatted string before splitting
345+ # it into different groups.
346+ end_index = rfc3966_format .find (U_SEMICOLON )
347+ if end_index < 0 :
348+ end_index = len (rfc3966_format )
349+
350+ # The country-code will have a '-' following it.
351+ start_index = rfc3966_format .find (U_DASH ) + 1
352+ return rfc3966_format [start_index :end_index ].split (U_DASH )
353+
354+
355+ def _get_national_number_groups (numobj , formatting_pattern ):
356+ """Helper method to get the national-number part of a number, formatted without any national
357+ prefix, and return it as a set of digit blocks that should be formatted together according to
358+ the formatting pattern passed in."""
359+ # If a format is provided, we format the NSN only, and split that according to the separator.
360+ nsn = national_significant_number (numobj )
361+ return _format_nsn_using_pattern (nsn , formatting_pattern ,
362+ PhoneNumberFormat .RFC3966 ).split (U_DASH )
374363
375364
376365def _contains_more_than_one_slash_in_national_number (numobj , candidate ):
@@ -662,7 +651,7 @@ def _parse_and_verify(self, candidate, offset):
662651 return None
663652
664653 numobj = parse (candidate , self .preferred_region , keep_raw_input = True )
665- if _verify (self .leniency , numobj , candidate ):
654+ if _verify (self .leniency , numobj , candidate , self ):
666655 # We used parse(keep_raw_input=True) to create this number,
667656 # but for now we don't return the extra values parsed.
668657 # TODO: stop clearing all values here and switch all users
@@ -677,6 +666,28 @@ def _parse_and_verify(self, candidate, offset):
677666 pass
678667 return None
679668
669+ def _check_number_grouping_is_valid (self , numobj , candidate , checker ):
670+ normalized_candidate = normalize_digits_only (candidate , True ) # keep non-digits
671+ formatted_number_groups = _get_national_number_groups_without_pattern (numobj )
672+ if checker (numobj , normalized_candidate , formatted_number_groups ):
673+ return True
674+ # If this didn't pass, see if there are any alternate formats that match, and try them instead.
675+ alternate_formats = _ALT_NUMBER_FORMATS .get (numobj .country_code , None )
676+ nsn = national_significant_number (numobj )
677+ if alternate_formats is not None :
678+ for alternate_format in alternate_formats :
679+ if len (alternate_format .leading_digits_pattern ) > 0 :
680+ # There is only one leading digits pattern for alternate formats.
681+ pattern = re .compile (alternate_format .leading_digits_pattern [0 ])
682+ if not pattern .match (nsn ):
683+ # Leading digits don't match; try another one.
684+ continue
685+ formatted_number_groups = _get_national_number_groups (numobj , alternate_format )
686+ if checker (numobj , normalized_candidate , formatted_number_groups ):
687+ return True
688+ return False
689+
690+
680691 def has_next (self ):
681692 """Indicates whether there is another match available"""
682693 if self ._state == PhoneNumberMatcher ._NOT_READY :
0 commit comments