lib/telephone_number/parser.rb in telephone_number-0.1.0 vs lib/telephone_number/parser.rb in telephone_number-0.2.0
- old
+ new
@@ -1,39 +1,68 @@
module TelephoneNumber
module Parser
- KEYS_TO_SKIP = [TelephoneNumber::PhoneData::GENERAL,
- TelephoneNumber::PhoneData::AREA_CODE_OPTIONAL]
+ KEYS_TO_SKIP = [PhoneData::GENERAL, PhoneData::AREA_CODE_OPTIONAL]
def sanitize(input_number)
return input_number.gsub(/[^0-9]/, "")
end
- def extract_number_types(input_number, country)
- country_data = TelephoneNumber::PhoneData.phone_data[country.to_sym]
+ # returns an array of valid types for the normalized number
+ # if array is empty, we can assume that the number is invalid
+ def validate
+ return [] unless country_data
+ applicable_keys = country_data[PhoneData::VALIDATIONS].reject{ |key, _value| KEYS_TO_SKIP.include?(key) }
+ applicable_keys.map do |phone_type, validations|
+ full = "^(#{validations[PhoneData::VALID_PATTERN]})$"
+ phone_type.to_sym if normalized_number =~ Regexp.new(full)
+ end.compact
+ end
- return [input_number, nil] unless country_data
- country_code = country_data[TelephoneNumber::PhoneData::COUNTRY_CODE]
+ private
- reg_string = "^(#{country_code})?"
- reg_string += "(#{country_data[TelephoneNumber::PhoneData::NATIONAL_PREFIX]})?"
- reg_string += "(#{country_data[TelephoneNumber::PhoneData::VALIDATIONS]\
- [TelephoneNumber::PhoneData::GENERAL]\
- [TelephoneNumber::PhoneData::VALID_PATTERN]})$"
+ def build_normalized_number
+ return original_number unless country_data
+ country_code = country_data[PhoneData::COUNTRY_CODE]
- match_result = input_number.match(Regexp.new(reg_string)) || []
+ number_with_correct_prefix = parse_prefix
+ reg_string = "^(#{country_code})?"
+ reg_string << "(#{country_data[PhoneData::NATIONAL_PREFIX]})?"
+ reg_string << "(#{country_data[PhoneData::VALIDATIONS][PhoneData::GENERAL][PhoneData::VALID_PATTERN]})$"
+
+ match_result = number_with_correct_prefix.match(Regexp.new(reg_string))
+ return original_number unless match_result
prefix_results = [match_result[1], match_result[2]]
- without_prefix = input_number.sub(prefix_results.join, "")
- [without_prefix, "#{country_code}#{without_prefix}"]
+ number_with_correct_prefix.sub(prefix_results.join, '')
end
- def validate(normalized_number, country)
- country_data = TelephoneNumber::PhoneData.phone_data[country.to_sym]
- return [] unless country_data
- applicable_keys = country_data[TelephoneNumber::PhoneData::VALIDATIONS].reject{ |key, _value| KEYS_TO_SKIP.include?(key) }
- applicable_keys.map do |phone_type, validations|
- full = "^(#{country_data[TelephoneNumber::PhoneData::COUNTRY_CODE]})(#{validations[TelephoneNumber::PhoneData::VALID_PATTERN]})$"
- phone_type if normalized_number =~ Regexp.new(full)
- end.compact
+ def parse_prefix
+ return original_number unless country_data[:national_prefix_for_parsing]
+ duped = original_number.dup
+ match_object = duped.match(Regexp.new(country_data[:national_prefix_for_parsing]))
+
+ # we need to do the "start_with?" here because we need to make sure it's not finding
+ # something in the middle of the number. However, we can't modify the regex to do this
+ # for us because it will offset the match groups that are referenced in the transform rules
+ return original_number unless match_object && duped.start_with?(match_object[0])
+ if country_data[:national_prefix_transform_rule]
+ transform_national_prefix(duped, match_object)
+ else
+ duped.sub!(match_object[0], '')
+ end
+ end
+
+ def transform_national_prefix(duped, match_object)
+ if PhoneData::MOBILE_TOKEN_COUNTRIES.include?(country) && match_object.captures.any?
+ sprintf(build_format_string, duped.sub!(match_object[0], match_object[1]))
+ elsif match_object.captures.none?
+ duped.sub!(match_object[0], '')
+ else
+ sprintf(build_format_string, *match_object.captures)
+ end
+ end
+
+ def build_format_string
+ country_data[:national_prefix_transform_rule].gsub(/(\$\d)/) {|cap| "%#{cap.reverse}s"}
end
end
end