def _attempt_to_format_accrued_digits(self): for num_format in self._possible_formats: num_re = re.compile(num_format.pattern) if fullmatch(num_re, self._national_number): formatted_number = re.sub(num_re, num_format.format, self._national_number) return self._prefix_before_national_number + formatted_number return ""
def _parse_and_verify(self, candidate, offset): """Parses a phone number from the candidate using phonenumberutil.parse and verifies it matches the requested leniency. If parsing and verification succeed, a corresponding PhoneNumberMatch is returned, otherwise this method returns None. Arguments: candidate -- The candidate match. offset -- The offset of candidate within self.text. Returns the parsed and validated phone number match, or None. """ try: # Check the candidate doesn't contain any formatting which would # indicate that it really isn't a phone number. if not fullmatch(_MATCHING_BRACKETS, candidate): return None numobj = phonenumberutil.parse(candidate, self.preferred_region) if _verify(self.leniency, numobj): return PhoneNumberMatch(offset, candidate, numobj) except phonenumberutil.NumberParseException: # ignore and continue pass return None
def input_digit(self, next_char, remember_position=False): """Formats a phone number on-the-fly as each digit is entered. If remember_position is set, remembers the position where next_char is inserted, so that it can be retrieved later by using get_remembered_position. The remembered position will be automatically adjusted if additional formatting characters are later inserted/removed in front of next_char. Arguments: next_char -- The most recently entered digit of a phone number. Formatting characters are allowed, but as soon as they are encountered this method formats the number as entered and not "as you type" anymore. Full width digits and Arabic-indic digits are allowed, and will be shown as they are. remember_position -- Whether to track the position where next_char is inserted. Returns the partially formatted phone number. """ self._accrued_input += next_char if remember_position: self._original_position = len(self._accrued_input) # We do formatting on-the-fly only when each character entered is # either a plus sign or a digit. if not fullmatch(_VALID_START_CHAR_PATTERN, next_char): self._able_to_format = False if not self._able_to_format: self._current_output = self._accrued_input return self._current_output next_char = self._normalize_and_accrue_digits_and_plus_sign( next_char, remember_position) # We start to attempt to format only when at least # MIN_LEADING_DIGITS_LENGTH digits (the plus sign is counted as a # digit as well for this purpose) have been entered. len_input = len(self._accrued_input_without_formatting) if len_input >= 0 and len_input <= 2: self._current_output = self._accrued_input return self._current_output if len_input == 3: if self._attempt_to_extract_idd(): self._is_expecting_country_calling_code = True else: # No IDD or plus sign is found, must be entering in national format. self._remove_national_prefix_from_national_number() self._current_output = self._attempt_to_choose_formatting_pattern( ) return self._current_output if len_input <= 5: if self._is_expecting_country_calling_code: if self._attempt_to_extract_ccc(): self._is_expecting_country_calling_code = False self._current_output = self._prefix_before_national_number + self._national_number return self._current_output if len_input <= 6: # We make a last attempt to extract a country calling code at the # 6th digit because the maximum length of IDD and country calling # code are both 3. if self._is_expecting_country_calling_code and not self._attempt_to_extract_ccc( ): self._able_to_format = False self._current_output = self._accrued_input return self._current_output if len(self._possible_formats) > 0: # The formatting pattern is already chosen. temp_national_number = self._input_digit_helper(next_char) # See if the accrued digits can be formatted properly already. If # not, use the results from input_digit_helper, which does # formatting based on the formatting pattern chosen. formatted_number = self._attempt_to_format_accrued_digits() if len(formatted_number) > 0: self._current_output = formatted_number return self._current_output self._narrow_down_possible_formats(self._national_number) if self._maybe_create_new_template(): self._current_output = self._input_accrued_national_number() return self._current_output if self._able_to_format: self._current_output = self._prefix_before_national_number + temp_national_number return self._current_output else: # pragma no cover self._current_output = temp_national_number return self._current_output else: self._current_output = self._attempt_to_choose_formatting_pattern() return self._current_output
def _is_format_eligible(self, format): return fullmatch(_ELIGIBLE_FORMAT_PATTERN, format)
def input_digit(self, next_char, remember_position=False): """Formats a phone number on-the-fly as each digit is entered. If remember_position is set, remembers the position where next_char is inserted, so that it can be retrieved later by using get_remembered_position. The remembered position will be automatically adjusted if additional formatting characters are later inserted/removed in front of next_char. Arguments: next_char -- The most recently entered digit of a phone number. Formatting characters are allowed, but as soon as they are encountered this method formats the number as entered and not "as you type" anymore. Full width digits and Arabic-indic digits are allowed, and will be shown as they are. remember_position -- Whether to track the position where next_char is inserted. Returns the partially formatted phone number. """ self._accrued_input += next_char if remember_position: self._original_position = len(self._accrued_input) # We do formatting on-the-fly only when each character entered is # either a plus sign or a digit. if not fullmatch(_VALID_START_CHAR_PATTERN, next_char): self._able_to_format = False if not self._able_to_format: self._current_output = self._accrued_input return self._current_output next_char = self._normalize_and_accrue_digits_and_plus_sign(next_char, remember_position) # We start to attempt to format only when at least # MIN_LEADING_DIGITS_LENGTH digits (the plus sign is counted as a # digit as well for this purpose) have been entered. len_input = len(self._accrued_input_without_formatting) if len_input >= 0 and len_input <= 2: self._current_output = self._accrued_input return self._current_output if len_input == 3: if self._attempt_to_extract_idd(): self._is_expecting_country_calling_code = True else: # No IDD or plus sign is found, must be entering in national format. self._remove_national_prefix_from_national_number() self._current_output = self._attempt_to_choose_formatting_pattern() return self._current_output if len_input <= 5: if self._is_expecting_country_calling_code: if self._attempt_to_extract_ccc(): self._is_expecting_country_calling_code = False self._current_output = self._prefix_before_national_number + self._national_number return self._current_output if len_input <= 6: # We make a last attempt to extract a country calling code at the # 6th digit because the maximum length of IDD and country calling # code are both 3. if self._is_expecting_country_calling_code and not self._attempt_to_extract_ccc(): self._able_to_format = False self._current_output = self._accrued_input return self._current_output if len(self._possible_formats) > 0: # The formatting pattern is already chosen. temp_national_number = self._input_digit_helper(next_char) # See if the accrued digits can be formatted properly already. If # not, use the results from input_digit_helper, which does # formatting based on the formatting pattern chosen. formatted_number = self._attempt_to_format_accrued_digits() if len(formatted_number) > 0: self._current_output = formatted_number return self._current_output self._narrow_down_possible_formats(self._national_number) if self._maybe_create_new_template(): self._current_output = self._input_accrued_national_number() return self._current_output if self._able_to_format: self._current_output = self._prefix_before_national_number + temp_national_number return self._current_output else: # pragma no cover self._current_output = temp_national_number return self._current_output else: self._current_output = self._attempt_to_choose_formatting_pattern() return self._current_output