1
// Copyright (C) 2009 The Libphonenumber Authors
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
7
// http://www.apache.org/licenses/LICENSE-2.0
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
15
// Author: Shaopeng Jia
16
// Open-sourced by: Philippe Liard
18
#include "phonenumbers/phonenumberutil.h"
28
#include <google/protobuf/message_lite.h>
29
#include <unicode/uchar.h>
30
#include <unicode/utf8.h>
32
#include "phonenumbers/asyoutypeformatter.h"
33
#include "phonenumbers/base/basictypes.h"
34
#include "phonenumbers/base/logging.h"
35
#include "phonenumbers/base/memory/singleton.h"
36
#include "phonenumbers/default_logger.h"
37
#include "phonenumbers/encoding_utils.h"
38
#include "phonenumbers/metadata.h"
39
#include "phonenumbers/normalize_utf8.h"
40
#include "phonenumbers/phonemetadata.pb.h"
41
#include "phonenumbers/phonenumber.h"
42
#include "phonenumbers/phonenumber.pb.h"
43
#include "phonenumbers/regexp_adapter.h"
44
#include "phonenumbers/regexp_cache.h"
45
#include "phonenumbers/regexp_factory.h"
46
#include "phonenumbers/region_code.h"
47
#include "phonenumbers/stl_util.h"
48
#include "phonenumbers/stringutil.h"
49
#include "phonenumbers/utf/unicodetext.h"
50
#include "phonenumbers/utf/utf.h"
53
namespace phonenumbers {
55
using google::protobuf::RepeatedPtrField;
58
const size_t PhoneNumberUtil::kMinLengthForNsn;
59
const size_t PhoneNumberUtil::kMaxLengthForNsn;
60
const size_t PhoneNumberUtil::kMaxLengthCountryCode;
61
const int PhoneNumberUtil::kNanpaCountryCode;
64
const char PhoneNumberUtil::kPlusChars[] = "+\xEF\xBC\x8B"; /* "++" */
65
// To find out the unicode code-point of the characters below in vim, highlight
66
// the character and type 'ga'. Note that the - is used to express ranges of
67
// full-width punctuation below, as well as being present in the expression
68
// itself. In emacs, you can use M-x unicode-what to query information about the
71
const char PhoneNumberUtil::kValidPunctuation[] =
72
/* "-x‐-―−ー--/ <U+200B><U+2060> ()()[].\\[\\]/~⁓∼" */
73
"-x\xE2\x80\x90-\xE2\x80\x95\xE2\x88\x92\xE3\x83\xBC\xEF\xBC\x8D-\xEF\xBC"
74
"\x8F \xC2\xA0\xC2\xAD\xE2\x80\x8B\xE2\x81\xA0\xE3\x80\x80()\xEF\xBC\x88"
75
"\xEF\xBC\x89\xEF\xBC\xBB\xEF\xBC\xBD.\\[\\]/~\xE2\x81\x93\xE2\x88\xBC";
78
const char PhoneNumberUtil::kCaptureUpToSecondNumberStart[] = "(.*)[\\\\/] *x";
81
const char PhoneNumberUtil::kRegionCodeForNonGeoEntity[] = "001";
85
// The prefix that needs to be inserted in front of a Colombian landline
86
// number when dialed from a mobile phone in Colombia.
87
const char kColombiaMobileToFixedLinePrefix[] = "3";
89
// The kPlusSign signifies the international prefix.
90
const char kPlusSign[] = "+";
92
const char kStarSign[] = "*";
94
const char kRfc3966ExtnPrefix[] = ";ext=";
95
const char kRfc3966Prefix[] = "tel:";
96
const char kRfc3966PhoneContext[] = ";phone-context=";
97
const char kRfc3966IsdnSubaddress[] = ";isub=";
99
const char kDigits[] = "\\p{Nd}";
100
// We accept alpha characters in phone numbers, ASCII only. We store lower-case
101
// here only since our regular expressions are case-insensitive.
102
const char kValidAlpha[] = "a-z";
104
// Default extension prefix to use when formatting. This will be put in front of
105
// any extension component of the number, after the main national number is
106
// formatted. For example, if you wish the default extension formatting to be "
107
// extn: 3456", then you should specify " extn: " here as the default extension
108
// prefix. This can be overridden by region-specific preferences.
109
const char kDefaultExtnPrefix[] = " ext. ";
111
// One-character symbols that can be used to indicate an extension.
112
const char kSingleExtnSymbolsForMatching[] =
113
"x\xEF\xBD\x98#\xEF\xBC\x83~\xEF\xBD\x9E";
115
bool LoadCompiledInMetadata(PhoneMetadataCollection* metadata) {
116
if (!metadata->ParseFromArray(metadata_get(), metadata_size())) {
117
LOG(ERROR) << "Could not parse binary data.";
123
// Returns a pointer to the description inside the metadata of the appropriate
125
const PhoneNumberDesc* GetNumberDescByType(
126
const PhoneMetadata& metadata,
127
PhoneNumberUtil::PhoneNumberType type) {
129
case PhoneNumberUtil::PREMIUM_RATE:
130
return &metadata.premium_rate();
131
case PhoneNumberUtil::TOLL_FREE:
132
return &metadata.toll_free();
133
case PhoneNumberUtil::MOBILE:
134
return &metadata.mobile();
135
case PhoneNumberUtil::FIXED_LINE:
136
case PhoneNumberUtil::FIXED_LINE_OR_MOBILE:
137
return &metadata.fixed_line();
138
case PhoneNumberUtil::SHARED_COST:
139
return &metadata.shared_cost();
140
case PhoneNumberUtil::VOIP:
141
return &metadata.voip();
142
case PhoneNumberUtil::PERSONAL_NUMBER:
143
return &metadata.personal_number();
144
case PhoneNumberUtil::PAGER:
145
return &metadata.pager();
146
case PhoneNumberUtil::UAN:
147
return &metadata.uan();
148
case PhoneNumberUtil::VOICEMAIL:
149
return &metadata.voicemail();
151
return &metadata.general_desc();
155
// A helper function that is used by Format and FormatByPattern.
156
void PrefixNumberWithCountryCallingCode(
157
int country_calling_code,
158
PhoneNumberUtil::PhoneNumberFormat number_format,
159
string* formatted_number) {
160
switch (number_format) {
161
case PhoneNumberUtil::E164:
162
formatted_number->insert(0, StrCat(kPlusSign, country_calling_code));
164
case PhoneNumberUtil::INTERNATIONAL:
165
formatted_number->insert(0, StrCat(kPlusSign, country_calling_code, " "));
167
case PhoneNumberUtil::RFC3966:
168
formatted_number->insert(0, StrCat(kRfc3966Prefix, kPlusSign,
169
country_calling_code, "-"));
171
case PhoneNumberUtil::NATIONAL:
178
// Returns true when one national number is the suffix of the other or both are
180
bool IsNationalNumberSuffixOfTheOther(const PhoneNumber& first_number,
181
const PhoneNumber& second_number) {
182
const string& first_number_national_number =
183
SimpleItoa(static_cast<uint64>(first_number.national_number()));
184
const string& second_number_national_number =
185
SimpleItoa(static_cast<uint64>(second_number.national_number()));
186
// Note that HasSuffixString returns true if the numbers are equal.
187
return HasSuffixString(first_number_national_number,
188
second_number_national_number) ||
189
HasSuffixString(second_number_national_number,
190
first_number_national_number);
193
char32 ToUnicodeCodepoint(const char* unicode_char) {
195
EncodingUtils::DecodeUTF8Char(unicode_char, &codepoint);
199
// Helper initialiser method to create the regular-expression pattern to match
200
// extensions, allowing the one-codepoint extension symbols provided by
201
// single_extn_symbols.
202
// Note that there are currently three capturing groups for the extension itself
203
// - if this number is changed, MaybeStripExtension needs to be updated.
204
string CreateExtnPattern(const string& single_extn_symbols) {
205
static const string capturing_extn_digits = StrCat("([", kDigits, "]{1,7})");
206
// The first regular expression covers RFC 3966 format, where the extension is
207
// added using ";ext=". The second more generic one starts with optional white
208
// space and ends with an optional full stop (.), followed by zero or more
209
// spaces/tabs and then the numbers themselves. The third one covers the
210
// special case of American numbers where the extension is written with a hash
211
// at the end, such as "- 503#".
212
// Note that the only capturing groups should be around the digits that you
213
// want to capture as part of the extension, or else parsing will fail!
214
// Canonical-equivalence doesn't seem to be an option with RE2, so we allow
215
// two options for representing the ó - the character itself, and one in the
216
// unicode decomposed form with the combining acute accent.
218
kRfc3966ExtnPrefix, capturing_extn_digits, "|"
219
/* "[ \\t,]*(?:e?xt(?:ensi(?:ó?|ó))?n?|e?xtn?|single_extn_symbols|"
221
"[:\\..]?[ \\t,-]*", capturing_extn_digits, "#?|" */
222
"[ \xC2\xA0\\t,]*(?:e?xt(?:ensi(?:o\xCC\x81?|\xC3\xB3))?n?|"
223
"(?:\xEF\xBD\x85)?\xEF\xBD\x98\xEF\xBD\x94(?:\xEF\xBD\x8E)?|"
224
"[", single_extn_symbols, "]|int|"
225
"\xEF\xBD\x89\xEF\xBD\x8E\xEF\xBD\x94|anexo)"
226
"[:\\.\xEF\xBC\x8E]?[ \xC2\xA0\\t,-]*", capturing_extn_digits,
227
"#?|[- ]+([", kDigits, "]{1,5})#"));
230
// Normalizes a string of characters representing a phone number by replacing
231
// all characters found in the accompanying map with the values therein, and
232
// stripping all other characters if remove_non_matches is true.
234
// number - a pointer to a string of characters representing a phone number to
236
// normalization_replacements - a mapping of characters to what they should be
237
// replaced by in the normalized version of the phone number
238
// remove_non_matches - indicates whether characters that are not able to be
239
// replaced should be stripped from the number. If this is false, they will be
240
// left unchanged in the number.
241
void NormalizeHelper(const map<char32, char>& normalization_replacements,
242
bool remove_non_matches,
245
UnicodeText number_as_unicode;
246
number_as_unicode.PointToUTF8(number->data(), number->size());
247
string normalized_number;
248
char unicode_char[5];
249
for (UnicodeText::const_iterator it = number_as_unicode.begin();
250
it != number_as_unicode.end();
252
map<char32, char>::const_iterator found_glyph_pair =
253
normalization_replacements.find(*it);
254
if (found_glyph_pair != normalization_replacements.end()) {
255
normalized_number.push_back(found_glyph_pair->second);
256
} else if (!remove_non_matches) {
257
// Find out how long this unicode char is so we can append it all.
258
int char_len = it.get_utf8(unicode_char);
259
normalized_number.append(unicode_char, char_len);
261
// If neither of the above are true, we remove this character.
263
number->assign(normalized_number);
266
PhoneNumberUtil::ValidationResult TestNumberLengthAgainstPattern(
267
const RegExp& number_pattern, const string& number) {
268
string extracted_number;
269
if (number_pattern.FullMatch(number, &extracted_number)) {
270
return PhoneNumberUtil::IS_POSSIBLE;
272
if (number_pattern.PartialMatch(number, &extracted_number)) {
273
return PhoneNumberUtil::TOO_LONG;
275
return PhoneNumberUtil::TOO_SHORT;
281
void PhoneNumberUtil::SetLogger(Logger* logger) {
282
logger_.reset(logger);
283
Logger::set_logger_impl(logger_.get());
286
class PhoneNumberRegExpsAndMappings {
288
void InitializeMapsAndSets() {
289
diallable_char_mappings_.insert(std::make_pair('+', '+'));
290
diallable_char_mappings_.insert(std::make_pair('*', '*'));
291
// Here we insert all punctuation symbols that we wish to respect when
292
// formatting alpha numbers, as they show the intended number groupings.
293
all_plus_number_grouping_symbols_.insert(
294
std::make_pair(ToUnicodeCodepoint("-"), '-'));
295
all_plus_number_grouping_symbols_.insert(
296
std::make_pair(ToUnicodeCodepoint("\xEF\xBC\x8D" /* "-" */), '-'));
297
all_plus_number_grouping_symbols_.insert(
298
std::make_pair(ToUnicodeCodepoint("\xE2\x80\x90" /* "‐" */), '-'));
299
all_plus_number_grouping_symbols_.insert(
300
std::make_pair(ToUnicodeCodepoint("\xE2\x80\x91" /* "‑" */), '-'));
301
all_plus_number_grouping_symbols_.insert(
302
std::make_pair(ToUnicodeCodepoint("\xE2\x80\x92" /* "‒" */), '-'));
303
all_plus_number_grouping_symbols_.insert(
304
std::make_pair(ToUnicodeCodepoint("\xE2\x80\x93" /* "–" */), '-'));
305
all_plus_number_grouping_symbols_.insert(
306
std::make_pair(ToUnicodeCodepoint("\xE2\x80\x94" /* "—" */), '-'));
307
all_plus_number_grouping_symbols_.insert(
308
std::make_pair(ToUnicodeCodepoint("\xE2\x80\x95" /* "―" */), '-'));
309
all_plus_number_grouping_symbols_.insert(
310
std::make_pair(ToUnicodeCodepoint("\xE2\x88\x92" /* "−" */), '-'));
311
all_plus_number_grouping_symbols_.insert(
312
std::make_pair(ToUnicodeCodepoint("/"), '/'));
313
all_plus_number_grouping_symbols_.insert(
314
std::make_pair(ToUnicodeCodepoint("\xEF\xBC\x8F" /* "/" */), '/'));
315
all_plus_number_grouping_symbols_.insert(
316
std::make_pair(ToUnicodeCodepoint(" "), ' '));
317
all_plus_number_grouping_symbols_.insert(
318
std::make_pair(ToUnicodeCodepoint("\xE3\x80\x80" /* " " */), ' '));
319
all_plus_number_grouping_symbols_.insert(
320
std::make_pair(ToUnicodeCodepoint("\xE2\x81\xA0"), ' '));
321
all_plus_number_grouping_symbols_.insert(
322
std::make_pair(ToUnicodeCodepoint("."), '.'));
323
all_plus_number_grouping_symbols_.insert(
324
std::make_pair(ToUnicodeCodepoint("\xEF\xBC\x8E" /* "." */), '.'));
325
// Only the upper-case letters are added here - the lower-case versions are
326
// added programmatically.
327
alpha_mappings_.insert(std::make_pair(ToUnicodeCodepoint("A"), '2'));
328
alpha_mappings_.insert(std::make_pair(ToUnicodeCodepoint("B"), '2'));
329
alpha_mappings_.insert(std::make_pair(ToUnicodeCodepoint("C"), '2'));
330
alpha_mappings_.insert(std::make_pair(ToUnicodeCodepoint("D"), '3'));
331
alpha_mappings_.insert(std::make_pair(ToUnicodeCodepoint("E"), '3'));
332
alpha_mappings_.insert(std::make_pair(ToUnicodeCodepoint("F"), '3'));
333
alpha_mappings_.insert(std::make_pair(ToUnicodeCodepoint("G"), '4'));
334
alpha_mappings_.insert(std::make_pair(ToUnicodeCodepoint("H"), '4'));
335
alpha_mappings_.insert(std::make_pair(ToUnicodeCodepoint("I"), '4'));
336
alpha_mappings_.insert(std::make_pair(ToUnicodeCodepoint("J"), '5'));
337
alpha_mappings_.insert(std::make_pair(ToUnicodeCodepoint("K"), '5'));
338
alpha_mappings_.insert(std::make_pair(ToUnicodeCodepoint("L"), '5'));
339
alpha_mappings_.insert(std::make_pair(ToUnicodeCodepoint("M"), '6'));
340
alpha_mappings_.insert(std::make_pair(ToUnicodeCodepoint("N"), '6'));
341
alpha_mappings_.insert(std::make_pair(ToUnicodeCodepoint("O"), '6'));
342
alpha_mappings_.insert(std::make_pair(ToUnicodeCodepoint("P"), '7'));
343
alpha_mappings_.insert(std::make_pair(ToUnicodeCodepoint("Q"), '7'));
344
alpha_mappings_.insert(std::make_pair(ToUnicodeCodepoint("R"), '7'));
345
alpha_mappings_.insert(std::make_pair(ToUnicodeCodepoint("S"), '7'));
346
alpha_mappings_.insert(std::make_pair(ToUnicodeCodepoint("T"), '8'));
347
alpha_mappings_.insert(std::make_pair(ToUnicodeCodepoint("U"), '8'));
348
alpha_mappings_.insert(std::make_pair(ToUnicodeCodepoint("V"), '8'));
349
alpha_mappings_.insert(std::make_pair(ToUnicodeCodepoint("W"), '9'));
350
alpha_mappings_.insert(std::make_pair(ToUnicodeCodepoint("X"), '9'));
351
alpha_mappings_.insert(std::make_pair(ToUnicodeCodepoint("Y"), '9'));
352
alpha_mappings_.insert(std::make_pair(ToUnicodeCodepoint("Z"), '9'));
353
map<char32, char> lower_case_mappings;
354
map<char32, char> alpha_letters;
355
for (map<char32, char>::const_iterator it = alpha_mappings_.begin();
356
it != alpha_mappings_.end();
358
// Convert all the upper-case ASCII letters to lower-case.
359
if (it->first < 128) {
360
char letter_as_upper = static_cast<char>(it->first);
361
char32 letter_as_lower = static_cast<char32>(tolower(letter_as_upper));
362
lower_case_mappings.insert(std::make_pair(letter_as_lower, it->second));
363
// Add the letters in both variants to the alpha_letters map. This just
364
// pairs each letter with its upper-case representation so that it can
365
// be retained when normalising alpha numbers.
366
alpha_letters.insert(std::make_pair(letter_as_lower, letter_as_upper));
367
alpha_letters.insert(std::make_pair(it->first, letter_as_upper));
370
// In the Java version we don't insert the lower-case mappings in the map,
371
// because we convert to upper case on the fly. Doing this here would
372
// involve pulling in all of ICU, which we don't want to do if we don't have
374
alpha_mappings_.insert(lower_case_mappings.begin(),
375
lower_case_mappings.end());
376
alpha_phone_mappings_.insert(alpha_mappings_.begin(),
377
alpha_mappings_.end());
378
all_plus_number_grouping_symbols_.insert(alpha_letters.begin(),
379
alpha_letters.end());
380
// Add the ASCII digits so that they don't get deleted by NormalizeHelper().
381
for (char c = '0'; c <= '9'; ++c) {
382
diallable_char_mappings_.insert(std::make_pair(c, c));
383
alpha_phone_mappings_.insert(std::make_pair(c, c));
384
all_plus_number_grouping_symbols_.insert(std::make_pair(c, c));
387
mobile_token_mappings_.insert(std::make_pair(52, '1'));
388
mobile_token_mappings_.insert(std::make_pair(54, '9'));
391
// Small string helpers since StrCat has a maximum number of arguments. These
392
// are both used to build valid_phone_number_.
393
const string punctuation_and_star_sign_;
394
const string min_length_phone_number_pattern_;
396
// Regular expression of viable phone numbers. This is location independent.
397
// Checks we have at least three leading digits, and only valid punctuation,
398
// alpha characters and digits in the phone number. Does not include extension
399
// data. The symbol 'x' is allowed here as valid punctuation since it is often
400
// used as a placeholder for carrier codes, for example in Brazilian phone
401
// numbers. We also allow multiple plus-signs at the start.
402
// Corresponds to the following:
403
// [digits]{minLengthNsn}|
404
// plus_sign*(([punctuation]|[star])*[digits]){3,}
405
// ([punctuation]|[star]|[digits]|[alpha])*
407
// The first reg-ex is to allow short numbers (two digits long) to be parsed
408
// if they are entered as "15" etc, but only if there is no punctuation in
409
// them. The second expression restricts the number of digits to three or
410
// more, but then allows them to be in international form, and to have
411
// alpha-characters and punctuation.
412
const string valid_phone_number_;
414
// Regexp of all possible ways to write extensions, for use when parsing. This
415
// will be run as a case-insensitive regexp match. Wide character versions are
416
// also provided after each ASCII version.
417
// For parsing, we are slightly more lenient in our interpretation than for
418
// matching. Here we allow a "comma" as a possible extension indicator. When
419
// matching, this is hardly ever used to indicate this.
420
const string extn_patterns_for_parsing_;
423
scoped_ptr<const AbstractRegExpFactory> regexp_factory_;
424
scoped_ptr<RegExpCache> regexp_cache_;
426
// A map that contains characters that are essential when dialling. That means
427
// any of the characters in this map must not be removed from a number when
428
// dialing, otherwise the call will not reach the intended destination.
429
map<char32, char> diallable_char_mappings_;
430
// These mappings map a character (key) to a specific digit that should
431
// replace it for normalization purposes.
432
map<char32, char> alpha_mappings_;
433
// For performance reasons, store a map of combining alpha_mappings with ASCII
435
map<char32, char> alpha_phone_mappings_;
437
// Separate map of all symbols that we wish to retain when formatting alpha
438
// numbers. This includes digits, ascii letters and number grouping symbols
439
// such as "-" and " ".
440
map<char32, char> all_plus_number_grouping_symbols_;
442
// Map of country calling codes that use a mobile token before the area code.
443
// One example of when this is relevant is when determining the length of the
444
// national destination code, which should be the length of the area code plus
445
// the length of the mobile token.
446
map<int, char> mobile_token_mappings_;
448
// Pattern that makes it easy to distinguish whether a region has a unique
449
// international dialing prefix or not. If a region has a unique international
450
// prefix (e.g. 011 in USA), it will be represented as a string that contains
451
// a sequence of ASCII digits. If there are multiple available international
452
// prefixes in a region, they will be represented as a regex string that
453
// always contains character(s) other than ASCII digits.
454
// Note this regex also includes tilde, which signals waiting for the tone.
455
scoped_ptr<const RegExp> unique_international_prefix_;
457
scoped_ptr<const RegExp> digits_pattern_;
458
scoped_ptr<const RegExp> capturing_digit_pattern_;
459
scoped_ptr<const RegExp> capturing_ascii_digits_pattern_;
461
// Regular expression of acceptable characters that may start a phone number
462
// for the purposes of parsing. This allows us to strip away meaningless
463
// prefixes to phone numbers that may be mistakenly given to us. This consists
464
// of digits, the plus symbol and arabic-indic digits. This does not contain
465
// alpha characters, although they may be used later in the number. It also
466
// does not include other punctuation, as this will be stripped later during
467
// parsing and is of no information value when parsing a number. The string
468
// starting with this valid character is captured.
469
// This corresponds to VALID_START_CHAR in the java version.
470
scoped_ptr<const RegExp> valid_start_char_pattern_;
472
// Regular expression of valid characters before a marker that might indicate
474
scoped_ptr<const RegExp> capture_up_to_second_number_start_pattern_;
476
// Regular expression of trailing characters that we want to remove. We remove
477
// all characters that are not alpha or numerical characters. The hash
478
// character is retained here, as it may signify the previous block was an
479
// extension. Note the capturing block at the start to capture the rest of the
480
// number if this was a match.
481
// This corresponds to UNWANTED_END_CHAR_PATTERN in the java version.
482
scoped_ptr<const RegExp> unwanted_end_char_pattern_;
484
// Regular expression of groups of valid punctuation characters.
485
scoped_ptr<const RegExp> separator_pattern_;
487
// Regexp of all possible ways to write extensions, for use when finding phone
488
// numbers in text. This will be run as a case-insensitive regexp match. Wide
489
// character versions are also provided after each ASCII version.
490
const string extn_patterns_for_matching_;
492
// Regexp of all known extension prefixes used by different regions followed
493
// by 1 or more valid digits, for use when parsing.
494
scoped_ptr<const RegExp> extn_pattern_;
496
// We append optionally the extension pattern to the end here, as a valid
497
// phone number may have an extension prefix appended, followed by 1 or more
499
scoped_ptr<const RegExp> valid_phone_number_pattern_;
501
// We use this pattern to check if the phone number has at least three letters
502
// in it - if so, then we treat it as a number where some phone-number digits
503
// are represented by letters.
504
scoped_ptr<const RegExp> valid_alpha_phone_pattern_;
506
scoped_ptr<const RegExp> first_group_capturing_pattern_;
508
scoped_ptr<const RegExp> carrier_code_pattern_;
510
scoped_ptr<const RegExp> plus_chars_pattern_;
512
PhoneNumberRegExpsAndMappings()
513
: punctuation_and_star_sign_(StrCat(PhoneNumberUtil::kValidPunctuation,
515
min_length_phone_number_pattern_(
516
StrCat(kDigits, "{", PhoneNumberUtil::kMinLengthForNsn, "}")),
518
StrCat(min_length_phone_number_pattern_, "|[",
519
PhoneNumberUtil::kPlusChars, "]*(?:[",
520
punctuation_and_star_sign_, "]*",
521
kDigits, "){3,}[", kValidAlpha,
522
punctuation_and_star_sign_, kDigits,
524
extn_patterns_for_parsing_(
525
CreateExtnPattern(StrCat(",", kSingleExtnSymbolsForMatching))),
526
regexp_factory_(new RegExpFactory()),
527
regexp_cache_(new RegExpCache(*regexp_factory_.get(), 128)),
528
diallable_char_mappings_(),
530
alpha_phone_mappings_(),
531
all_plus_number_grouping_symbols_(),
532
mobile_token_mappings_(),
533
unique_international_prefix_(regexp_factory_->CreateRegExp(
534
/* "[\\d]+(?:[~⁓∼~][\\d]+)?" */
535
"[\\d]+(?:[~\xE2\x81\x93\xE2\x88\xBC\xEF\xBD\x9E][\\d]+)?")),
537
regexp_factory_->CreateRegExp(StrCat("[", kDigits, "]*"))),
538
capturing_digit_pattern_(
539
regexp_factory_->CreateRegExp(StrCat("([", kDigits, "])"))),
540
capturing_ascii_digits_pattern_(
541
regexp_factory_->CreateRegExp("(\\d+)")),
542
valid_start_char_pattern_(regexp_factory_->CreateRegExp(
543
StrCat("[", PhoneNumberUtil::kPlusChars, kDigits, "]"))),
544
capture_up_to_second_number_start_pattern_(
545
regexp_factory_->CreateRegExp(
546
PhoneNumberUtil::kCaptureUpToSecondNumberStart)),
547
unwanted_end_char_pattern_(
548
regexp_factory_->CreateRegExp("[^\\p{N}\\p{L}#]")),
550
regexp_factory_->CreateRegExp(
551
StrCat("[", PhoneNumberUtil::kValidPunctuation, "]+"))),
552
extn_patterns_for_matching_(
553
CreateExtnPattern(kSingleExtnSymbolsForMatching)),
554
extn_pattern_(regexp_factory_->CreateRegExp(
555
StrCat("(?i)(?:", extn_patterns_for_parsing_, ")$"))),
556
valid_phone_number_pattern_(regexp_factory_->CreateRegExp(
557
StrCat("(?i)", valid_phone_number_,
558
"(?:", extn_patterns_for_parsing_, ")?"))),
559
valid_alpha_phone_pattern_(regexp_factory_->CreateRegExp(
560
StrCat("(?i)(?:.*?[", kValidAlpha, "]){3}"))),
561
// The first_group_capturing_pattern was originally set to $1 but there
562
// are some countries for which the first group is not used in the
563
// national pattern (e.g. Argentina) so the $1 group does not match
564
// correctly. Therefore, we use \d, so that the first group actually
565
// used in the pattern will be matched.
566
first_group_capturing_pattern_(
567
regexp_factory_->CreateRegExp("(\\$\\d)")),
568
carrier_code_pattern_(regexp_factory_->CreateRegExp("\\$CC")),
570
regexp_factory_->CreateRegExp(
571
StrCat("[", PhoneNumberUtil::kPlusChars, "]+"))) {
572
InitializeMapsAndSets();
576
DISALLOW_COPY_AND_ASSIGN(PhoneNumberRegExpsAndMappings);
579
// Private constructor. Also takes care of initialisation.
580
PhoneNumberUtil::PhoneNumberUtil()
581
: logger_(Logger::set_logger_impl(new NullLogger())),
582
reg_exps_(new PhoneNumberRegExpsAndMappings),
583
country_calling_code_to_region_code_map_(new vector<IntRegionsPair>()),
584
nanpa_regions_(new set<string>()),
585
region_to_metadata_map_(new map<string, PhoneMetadata>()),
586
country_code_to_non_geographical_metadata_map_(
587
new map<int, PhoneMetadata>) {
588
Logger::set_logger_impl(logger_.get());
589
// TODO: Update the java version to put the contents of the init
590
// method inside the constructor as well to keep both in sync.
591
PhoneMetadataCollection metadata_collection;
592
if (!LoadCompiledInMetadata(&metadata_collection)) {
593
LOG(DFATAL) << "Could not parse compiled-in metadata.";
596
// Storing data in a temporary map to make it easier to find other regions
597
// that share a country calling code when inserting data.
598
map<int, list<string>* > country_calling_code_to_region_map;
599
for (RepeatedPtrField<PhoneMetadata>::const_iterator it =
600
metadata_collection.metadata().begin();
601
it != metadata_collection.metadata().end();
603
const string& region_code = it->id();
604
if (region_code == RegionCode::GetUnknown()) {
608
int country_calling_code = it->country_code();
609
if (kRegionCodeForNonGeoEntity == region_code) {
610
country_code_to_non_geographical_metadata_map_->insert(
611
std::make_pair(country_calling_code, *it));
613
region_to_metadata_map_->insert(std::make_pair(region_code, *it));
615
map<int, list<string>* >::iterator calling_code_in_map =
616
country_calling_code_to_region_map.find(country_calling_code);
617
if (calling_code_in_map != country_calling_code_to_region_map.end()) {
618
if (it->main_country_for_code()) {
619
calling_code_in_map->second->push_front(region_code);
621
calling_code_in_map->second->push_back(region_code);
624
// For most country calling codes, there will be only one region code.
625
list<string>* list_with_region_code = new list<string>();
626
list_with_region_code->push_back(region_code);
627
country_calling_code_to_region_map.insert(
628
std::make_pair(country_calling_code, list_with_region_code));
630
if (country_calling_code == kNanpaCountryCode) {
631
nanpa_regions_->insert(region_code);
635
country_calling_code_to_region_code_map_->insert(
636
country_calling_code_to_region_code_map_->begin(),
637
country_calling_code_to_region_map.begin(),
638
country_calling_code_to_region_map.end());
639
// Sort all the pairs in ascending order according to country calling code.
640
std::sort(country_calling_code_to_region_code_map_->begin(),
641
country_calling_code_to_region_code_map_->end(),
645
PhoneNumberUtil::~PhoneNumberUtil() {
646
STLDeleteContainerPairSecondPointers(
647
country_calling_code_to_region_code_map_->begin(),
648
country_calling_code_to_region_code_map_->end());
651
void PhoneNumberUtil::GetSupportedRegions(set<string>* regions) const {
653
for (map<string, PhoneMetadata>::const_iterator it =
654
region_to_metadata_map_->begin(); it != region_to_metadata_map_->end();
656
regions->insert(it->first);
660
void PhoneNumberUtil::GetSupportedGlobalNetworkCallingCodes(
661
set<int>* calling_codes) const {
662
DCHECK(calling_codes);
663
for (map<int, PhoneMetadata>::const_iterator it =
664
country_code_to_non_geographical_metadata_map_->begin();
665
it != country_code_to_non_geographical_metadata_map_->end(); ++it) {
666
calling_codes->insert(it->first);
670
// Public wrapper function to get a PhoneNumberUtil instance with the default
673
PhoneNumberUtil* PhoneNumberUtil::GetInstance() {
674
return Singleton<PhoneNumberUtil>::GetInstance();
677
const string& PhoneNumberUtil::GetExtnPatternsForMatching() const {
678
return reg_exps_->extn_patterns_for_matching_;
681
bool PhoneNumberUtil::StartsWithPlusCharsPattern(const string& number)
683
const scoped_ptr<RegExpInput> number_string_piece(
684
reg_exps_->regexp_factory_->CreateInput(number));
685
return reg_exps_->plus_chars_pattern_->Consume(number_string_piece.get());
688
bool PhoneNumberUtil::ContainsOnlyValidDigits(const string& s) const {
689
return reg_exps_->digits_pattern_->FullMatch(s);
692
void PhoneNumberUtil::TrimUnwantedEndChars(string* number) const {
694
UnicodeText number_as_unicode;
695
number_as_unicode.PointToUTF8(number->data(), number->size());
696
char current_char[5];
698
UnicodeText::const_reverse_iterator reverse_it(number_as_unicode.end());
699
for (; reverse_it.base() != number_as_unicode.begin(); ++reverse_it) {
700
len = reverse_it.get_utf8(current_char);
701
current_char[len] = '\0';
702
if (!reg_exps_->unwanted_end_char_pattern_->FullMatch(current_char)) {
707
number->assign(UnicodeText::UTF8Substring(number_as_unicode.begin(),
711
bool PhoneNumberUtil::IsFormatEligibleForAsYouTypeFormatter(
712
const string& format) const {
713
// A pattern that is used to determine if a numberFormat under
714
// availableFormats is eligible to be used by the AYTF. It is eligible when
715
// the format element under numberFormat contains groups of the dollar sign
716
// followed by a single digit, separated by valid phone number punctuation.
717
// This prevents invalid punctuation (such as the star sign in Israeli star
718
// numbers) getting into the output of the AYTF.
719
const RegExp& eligible_format_pattern = reg_exps_->regexp_cache_->GetRegExp(
720
StrCat("[", kValidPunctuation, "]*", "(\\$\\d", "[",
721
kValidPunctuation, "]*)+"));
722
return eligible_format_pattern.FullMatch(format);
725
bool PhoneNumberUtil::FormattingRuleHasFirstGroupOnly(
726
const string& national_prefix_formatting_rule) const {
727
// A pattern that is used to determine if the national prefix formatting rule
728
// has the first group only, i.e., does not start with the national prefix.
729
// Note that the pattern explicitly allows for unbalanced parentheses.
730
const RegExp& first_group_only_prefix_pattern =
731
reg_exps_->regexp_cache_->GetRegExp("\\(?\\$1\\)?");
732
return national_prefix_formatting_rule.empty() ||
733
first_group_only_prefix_pattern.FullMatch(
734
national_prefix_formatting_rule);
737
void PhoneNumberUtil::GetNddPrefixForRegion(const string& region_code,
738
bool strip_non_digits,
739
string* national_prefix) const {
740
DCHECK(national_prefix);
741
const PhoneMetadata* metadata = GetMetadataForRegion(region_code);
743
LOG(WARNING) << "Invalid or unknown region code (" << region_code
747
national_prefix->assign(metadata->national_prefix());
748
if (strip_non_digits) {
749
// Note: if any other non-numeric symbols are ever used in national
750
// prefixes, these would have to be removed here as well.
751
strrmm(national_prefix, "~");
755
bool PhoneNumberUtil::IsValidRegionCode(const string& region_code) const {
756
return (region_to_metadata_map_->find(region_code) !=
757
region_to_metadata_map_->end());
760
bool PhoneNumberUtil::HasValidCountryCallingCode(
761
int country_calling_code) const {
762
// Create an IntRegionsPair with the country_code passed in, and use it to
763
// locate the pair with the same country_code in the sorted vector.
764
IntRegionsPair target_pair;
765
target_pair.first = country_calling_code;
766
return (binary_search(country_calling_code_to_region_code_map_->begin(),
767
country_calling_code_to_region_code_map_->end(),
768
target_pair, OrderByFirst()));
771
// Returns a pointer to the phone metadata for the appropriate region or NULL
772
// if the region code is invalid or unknown.
773
const PhoneMetadata* PhoneNumberUtil::GetMetadataForRegion(
774
const string& region_code) const {
775
map<string, PhoneMetadata>::const_iterator it =
776
region_to_metadata_map_->find(region_code);
777
if (it != region_to_metadata_map_->end()) {
783
const PhoneMetadata* PhoneNumberUtil::GetMetadataForNonGeographicalRegion(
784
int country_calling_code) const {
785
map<int, PhoneMetadata>::const_iterator it =
786
country_code_to_non_geographical_metadata_map_->find(
787
country_calling_code);
788
if (it != country_code_to_non_geographical_metadata_map_->end()) {
794
void PhoneNumberUtil::Format(const PhoneNumber& number,
795
PhoneNumberFormat number_format,
796
string* formatted_number) const {
797
DCHECK(formatted_number);
798
if (number.national_number() == 0) {
799
const string& raw_input = number.raw_input();
800
if (!raw_input.empty()) {
801
// Unparseable numbers that kept their raw input just use that.
802
// This is the only case where a number can be formatted as E164 without a
803
// leading '+' symbol (but the original number wasn't parseable anyway).
804
// TODO: Consider removing the 'if' above so that unparseable
805
// strings without raw input format to the empty string instead of "+00".
806
formatted_number->assign(raw_input);
810
int country_calling_code = number.country_code();
811
string national_significant_number;
812
GetNationalSignificantNumber(number, &national_significant_number);
813
if (number_format == E164) {
814
// Early exit for E164 case (even if the country calling code is invalid)
815
// since no formatting of the national number needs to be applied.
816
// Extensions are not formatted.
817
formatted_number->assign(national_significant_number);
818
PrefixNumberWithCountryCallingCode(country_calling_code, E164,
822
if (!HasValidCountryCallingCode(country_calling_code)) {
823
formatted_number->assign(national_significant_number);
826
// Note here that all NANPA formatting rules are contained by US, so we use
827
// that to format NANPA numbers. The same applies to Russian Fed regions -
828
// rules are contained by Russia. French Indian Ocean country rules are
829
// contained by Réunion.
831
GetRegionCodeForCountryCode(country_calling_code, ®ion_code);
832
// Metadata cannot be NULL because the country calling code is valid (which
833
// means that the region code cannot be ZZ and must be one of our supported
835
const PhoneMetadata* metadata =
836
GetMetadataForRegionOrCallingCode(country_calling_code, region_code);
837
FormatNsn(national_significant_number, *metadata, number_format,
839
MaybeAppendFormattedExtension(number, *metadata, number_format,
841
PrefixNumberWithCountryCallingCode(country_calling_code, number_format,
845
void PhoneNumberUtil::FormatByPattern(
846
const PhoneNumber& number,
847
PhoneNumberFormat number_format,
848
const RepeatedPtrField<NumberFormat>& user_defined_formats,
849
string* formatted_number) const {
850
DCHECK(formatted_number);
851
int country_calling_code = number.country_code();
852
// Note GetRegionCodeForCountryCode() is used because formatting information
853
// for regions which share a country calling code is contained by only one
854
// region for performance reasons. For example, for NANPA regions it will be
855
// contained in the metadata for US.
856
string national_significant_number;
857
GetNationalSignificantNumber(number, &national_significant_number);
858
if (!HasValidCountryCallingCode(country_calling_code)) {
859
formatted_number->assign(national_significant_number);
863
GetRegionCodeForCountryCode(country_calling_code, ®ion_code);
864
// Metadata cannot be NULL because the country calling code is valid.
865
const PhoneMetadata* metadata =
866
GetMetadataForRegionOrCallingCode(country_calling_code, region_code);
867
const NumberFormat* formatting_pattern =
868
ChooseFormattingPatternForNumber(user_defined_formats,
869
national_significant_number);
870
if (!formatting_pattern) {
871
// If no pattern above is matched, we format the number as a whole.
872
formatted_number->assign(national_significant_number);
874
NumberFormat num_format_copy;
875
// Before we do a replacement of the national prefix pattern $NP with the
876
// national prefix, we need to copy the rule so that subsequent replacements
877
// for different numbers have the appropriate national prefix.
878
num_format_copy.MergeFrom(*formatting_pattern);
879
string national_prefix_formatting_rule(
880
formatting_pattern->national_prefix_formatting_rule());
881
if (!national_prefix_formatting_rule.empty()) {
882
const string& national_prefix = metadata->national_prefix();
883
if (!national_prefix.empty()) {
884
// Replace $NP with national prefix and $FG with the first group ($1).
885
GlobalReplaceSubstring("$NP", national_prefix,
886
&national_prefix_formatting_rule);
887
GlobalReplaceSubstring("$FG", "$1",
888
&national_prefix_formatting_rule);
889
num_format_copy.set_national_prefix_formatting_rule(
890
national_prefix_formatting_rule);
892
// We don't want to have a rule for how to format the national prefix if
894
num_format_copy.clear_national_prefix_formatting_rule();
897
FormatNsnUsingPattern(national_significant_number, num_format_copy,
898
number_format, formatted_number);
900
MaybeAppendFormattedExtension(number, *metadata, NATIONAL, formatted_number);
901
PrefixNumberWithCountryCallingCode(country_calling_code, number_format,
905
void PhoneNumberUtil::FormatNationalNumberWithCarrierCode(
906
const PhoneNumber& number,
907
const string& carrier_code,
908
string* formatted_number) const {
909
int country_calling_code = number.country_code();
910
string national_significant_number;
911
GetNationalSignificantNumber(number, &national_significant_number);
912
if (!HasValidCountryCallingCode(country_calling_code)) {
913
formatted_number->assign(national_significant_number);
917
// Note GetRegionCodeForCountryCode() is used because formatting information
918
// for regions which share a country calling code is contained by only one
919
// region for performance reasons. For example, for NANPA regions it will be
920
// contained in the metadata for US.
922
GetRegionCodeForCountryCode(country_calling_code, ®ion_code);
923
// Metadata cannot be NULL because the country calling code is valid.
924
const PhoneMetadata* metadata =
925
GetMetadataForRegionOrCallingCode(country_calling_code, region_code);
926
FormatNsnWithCarrier(national_significant_number, *metadata, NATIONAL,
927
carrier_code, formatted_number);
928
MaybeAppendFormattedExtension(number, *metadata, NATIONAL, formatted_number);
929
PrefixNumberWithCountryCallingCode(country_calling_code, NATIONAL,
933
const PhoneMetadata* PhoneNumberUtil::GetMetadataForRegionOrCallingCode(
934
int country_calling_code, const string& region_code) const {
935
return kRegionCodeForNonGeoEntity == region_code
936
? GetMetadataForNonGeographicalRegion(country_calling_code)
937
: GetMetadataForRegion(region_code);
940
void PhoneNumberUtil::FormatNationalNumberWithPreferredCarrierCode(
941
const PhoneNumber& number,
942
const string& fallback_carrier_code,
943
string* formatted_number) const {
944
FormatNationalNumberWithCarrierCode(
946
number.has_preferred_domestic_carrier_code()
947
? number.preferred_domestic_carrier_code()
948
: fallback_carrier_code,
952
void PhoneNumberUtil::FormatNumberForMobileDialing(
953
const PhoneNumber& number,
954
const string& calling_from,
955
bool with_formatting,
956
string* formatted_number) const {
957
int country_calling_code = number.country_code();
958
if (!HasValidCountryCallingCode(country_calling_code)) {
959
formatted_number->assign(number.has_raw_input() ? number.raw_input() : "");
963
formatted_number->assign("");
964
// Clear the extension, as that part cannot normally be dialed together with
966
PhoneNumber number_no_extension(number);
967
number_no_extension.clear_extension();
969
GetRegionCodeForCountryCode(country_calling_code, ®ion_code);
970
PhoneNumberType number_type = GetNumberType(number_no_extension);
971
bool is_valid_number = (number_type != UNKNOWN);
972
if (calling_from == region_code) {
973
bool is_fixed_line_or_mobile =
974
(number_type == FIXED_LINE) || (number_type == MOBILE) ||
975
(number_type == FIXED_LINE_OR_MOBILE);
976
// Carrier codes may be needed in some countries. We handle this here.
977
if ((region_code == "CO") && (number_type == FIXED_LINE)) {
978
FormatNationalNumberWithCarrierCode(
979
number_no_extension, kColombiaMobileToFixedLinePrefix,
981
} else if ((region_code == "BR") && (is_fixed_line_or_mobile)) {
982
if (number_no_extension.has_preferred_domestic_carrier_code()) {
983
FormatNationalNumberWithPreferredCarrierCode(number_no_extension, "",
986
// Brazilian fixed line and mobile numbers need to be dialed with a
987
// carrier code when called within Brazil. Without that, most of the
988
// carriers won't connect the call. Because of that, we return an empty
990
formatted_number->assign("");
992
} else if (is_valid_number && region_code == "HU") {
993
// The national format for HU numbers doesn't contain the national prefix,
994
// because that is how numbers are normally written down. However, the
995
// national prefix is obligatory when dialing from a mobile phone, except
996
// for short numbers. As a result, we add it back here if it is a valid
997
// regular length phone number.
998
Format(number_no_extension, NATIONAL, formatted_number);
999
string hu_national_prefix;
1000
GetNddPrefixForRegion(region_code, true /* strip non-digits */,
1001
&hu_national_prefix);
1002
formatted_number->assign(
1003
StrCat(hu_national_prefix, " ", *formatted_number));
1004
} else if (country_calling_code == kNanpaCountryCode) {
1005
// For NANPA countries, we output international format for numbers that
1006
// can be dialed internationally, since that always works, except for
1007
// numbers which might potentially be short numbers, which are always
1008
// dialled in national format.
1009
const PhoneMetadata* region_metadata = GetMetadataForRegion(calling_from);
1010
string national_number;
1011
GetNationalSignificantNumber(number_no_extension, &national_number);
1012
if (CanBeInternationallyDialled(number_no_extension) &&
1013
!IsShorterThanPossibleNormalNumber(region_metadata,
1015
Format(number_no_extension, INTERNATIONAL, formatted_number);
1017
Format(number_no_extension, NATIONAL, formatted_number);
1020
// For non-geographical countries, and Mexican and Chilean fixed line and
1021
// mobile numbers, we output international format for numbers that can be
1022
// dialed internationally as that always works.
1023
if ((region_code == kRegionCodeForNonGeoEntity ||
1024
// MX fixed line and mobile numbers should always be formatted in
1025
// international format, even when dialed within MX. For national
1026
// format to work, a carrier code needs to be used, and the correct
1027
// carrier code depends on if the caller and callee are from the same
1028
// local area. It is trickier to get that to work correctly than
1029
// using international format, which is tested to work fine on all
1031
// CL fixed line numbers need the national prefix when dialing in the
1032
// national format, but don't have it when used for display. The
1033
// reverse is true for mobile numbers. As a result, we output them in
1034
// the international format to make it work.
1035
((region_code == "MX" || region_code == "CL") &&
1036
is_fixed_line_or_mobile)) &&
1037
CanBeInternationallyDialled(number_no_extension)) {
1038
Format(number_no_extension, INTERNATIONAL, formatted_number);
1040
Format(number_no_extension, NATIONAL, formatted_number);
1043
} else if (is_valid_number &&
1044
CanBeInternationallyDialled(number_no_extension)) {
1045
// We assume that short numbers are not diallable from outside their
1046
// region, so if a number is not a valid regular length phone number, we
1047
// treat it as if it cannot be internationally dialled.
1049
? Format(number_no_extension, INTERNATIONAL, formatted_number)
1050
: Format(number_no_extension, E164, formatted_number);
1053
if (!with_formatting) {
1054
NormalizeDiallableCharsOnly(formatted_number);
1058
void PhoneNumberUtil::FormatOutOfCountryCallingNumber(
1059
const PhoneNumber& number,
1060
const string& calling_from,
1061
string* formatted_number) const {
1062
DCHECK(formatted_number);
1063
if (!IsValidRegionCode(calling_from)) {
1064
LOG(WARNING) << "Trying to format number from invalid region "
1066
<< ". International formatting applied.";
1067
Format(number, INTERNATIONAL, formatted_number);
1070
int country_code = number.country_code();
1071
string national_significant_number;
1072
GetNationalSignificantNumber(number, &national_significant_number);
1073
if (!HasValidCountryCallingCode(country_code)) {
1074
formatted_number->assign(national_significant_number);
1077
if (country_code == kNanpaCountryCode) {
1078
if (IsNANPACountry(calling_from)) {
1079
// For NANPA regions, return the national format for these regions but
1080
// prefix it with the country calling code.
1081
Format(number, NATIONAL, formatted_number);
1082
formatted_number->insert(0, StrCat(country_code, " "));
1085
} else if (country_code == GetCountryCodeForValidRegion(calling_from)) {
1086
// If neither region is a NANPA region, then we check to see if the
1087
// country calling code of the number and the country calling code of the
1088
// region we are calling from are the same.
1089
// For regions that share a country calling code, the country calling code
1090
// need not be dialled. This also applies when dialling within a region, so
1091
// this if clause covers both these cases.
1092
// Technically this is the case for dialling from la Réunion to other
1093
// overseas departments of France (French Guiana, Martinique, Guadeloupe),
1094
// but not vice versa - so we don't cover this edge case for now and for
1095
// those cases return the version including country calling code.
1097
// http://www.petitfute.com/voyage/225-info-pratiques-reunion
1098
Format(number, NATIONAL, formatted_number);
1101
// Metadata cannot be NULL because we checked 'IsValidRegionCode()' above.
1102
const PhoneMetadata* metadata_calling_from =
1103
GetMetadataForRegion(calling_from);
1104
const string& international_prefix =
1105
metadata_calling_from->international_prefix();
1107
// For regions that have multiple international prefixes, the international
1108
// format of the number is returned, unless there is a preferred international
1110
const string international_prefix_for_formatting(
1111
reg_exps_->unique_international_prefix_->FullMatch(international_prefix)
1112
? international_prefix
1113
: metadata_calling_from->preferred_international_prefix());
1116
GetRegionCodeForCountryCode(country_code, ®ion_code);
1117
// Metadata cannot be NULL because the country_code is valid.
1118
const PhoneMetadata* metadata_for_region =
1119
GetMetadataForRegionOrCallingCode(country_code, region_code);
1120
FormatNsn(national_significant_number, *metadata_for_region, INTERNATIONAL,
1122
MaybeAppendFormattedExtension(number, *metadata_for_region, INTERNATIONAL,
1124
if (!international_prefix_for_formatting.empty()) {
1125
formatted_number->insert(
1126
0, StrCat(international_prefix_for_formatting, " ", country_code, " "));
1128
PrefixNumberWithCountryCallingCode(country_code, INTERNATIONAL,
1133
void PhoneNumberUtil::FormatInOriginalFormat(const PhoneNumber& number,
1134
const string& region_calling_from,
1135
string* formatted_number) const {
1136
DCHECK(formatted_number);
1138
if (number.has_raw_input() &&
1139
(HasUnexpectedItalianLeadingZero(number) ||
1140
!HasFormattingPatternForNumber(number))) {
1141
// We check if we have the formatting pattern because without that, we might
1142
// format the number as a group without national prefix.
1143
formatted_number->assign(number.raw_input());
1146
if (!number.has_country_code_source()) {
1147
Format(number, NATIONAL, formatted_number);
1150
switch (number.country_code_source()) {
1151
case PhoneNumber::FROM_NUMBER_WITH_PLUS_SIGN:
1152
Format(number, INTERNATIONAL, formatted_number);
1154
case PhoneNumber::FROM_NUMBER_WITH_IDD:
1155
FormatOutOfCountryCallingNumber(number, region_calling_from,
1158
case PhoneNumber::FROM_NUMBER_WITHOUT_PLUS_SIGN:
1159
Format(number, INTERNATIONAL, formatted_number);
1160
formatted_number->erase(formatted_number->begin());
1162
case PhoneNumber::FROM_DEFAULT_COUNTRY:
1163
// Fall-through to default case.
1166
GetRegionCodeForCountryCode(number.country_code(), ®ion_code);
1167
// We strip non-digits from the NDD here, and from the raw input later, so
1168
// that we can compare them easily.
1169
string national_prefix;
1170
GetNddPrefixForRegion(region_code, true /* strip non-digits */,
1172
if (national_prefix.empty()) {
1173
// If the region doesn't have a national prefix at all, we can safely
1174
// return the national format without worrying about a national prefix
1176
Format(number, NATIONAL, formatted_number);
1179
// Otherwise, we check if the original number was entered with a national
1181
if (RawInputContainsNationalPrefix(number.raw_input(), national_prefix,
1183
// If so, we can safely return the national format.
1184
Format(number, NATIONAL, formatted_number);
1187
// Metadata cannot be NULL here because GetNddPrefixForRegion() (above)
1188
// leaves the prefix empty if there is no metadata for the region.
1189
const PhoneMetadata* metadata = GetMetadataForRegion(region_code);
1190
string national_number;
1191
GetNationalSignificantNumber(number, &national_number);
1192
// This shouldn't be NULL, because we have checked that above with
1193
// HasFormattingPatternForNumber.
1194
const NumberFormat* format_rule =
1195
ChooseFormattingPatternForNumber(metadata->number_format(),
1197
// The format rule could still be NULL here if the national number was 0
1198
// and there was no raw input (this should not be possible for numbers
1199
// generated by the phonenumber library as they would also not have a
1200
// country calling code and we would have exited earlier).
1202
Format(number, NATIONAL, formatted_number);
1205
// When the format we apply to this number doesn't contain national
1206
// prefix, we can just return the national format.
1207
// TODO: Refactor the code below with the code in
1208
// IsNationalPrefixPresentIfRequired.
1209
string candidate_national_prefix_rule(
1210
format_rule->national_prefix_formatting_rule());
1211
// We assume that the first-group symbol will never be _before_ the
1213
if (!candidate_national_prefix_rule.empty()) {
1214
candidate_national_prefix_rule.erase(
1215
candidate_national_prefix_rule.find("$1"));
1216
NormalizeDigitsOnly(&candidate_national_prefix_rule);
1218
if (candidate_national_prefix_rule.empty()) {
1219
// National prefix not used when formatting this number.
1220
Format(number, NATIONAL, formatted_number);
1223
// Otherwise, we need to remove the national prefix from our output.
1224
RepeatedPtrField<NumberFormat> number_formats;
1225
NumberFormat* number_format = number_formats.Add();
1226
number_format->MergeFrom(*format_rule);
1227
number_format->clear_national_prefix_formatting_rule();
1228
FormatByPattern(number, NATIONAL, number_formats, formatted_number);
1231
// If no digit is inserted/removed/modified as a result of our formatting, we
1232
// return the formatted phone number; otherwise we return the raw input the
1234
if (!formatted_number->empty() && !number.raw_input().empty()) {
1235
string normalized_formatted_number(*formatted_number);
1236
NormalizeDiallableCharsOnly(&normalized_formatted_number);
1237
string normalized_raw_input(number.raw_input());
1238
NormalizeDiallableCharsOnly(&normalized_raw_input);
1239
if (normalized_formatted_number != normalized_raw_input) {
1240
formatted_number->assign(number.raw_input());
1245
// Check if raw_input, which is assumed to be in the national format, has a
1246
// national prefix. The national prefix is assumed to be in digits-only form.
1247
bool PhoneNumberUtil::RawInputContainsNationalPrefix(
1248
const string& raw_input,
1249
const string& national_prefix,
1250
const string& region_code) const {
1251
string normalized_national_number(raw_input);
1252
NormalizeDigitsOnly(&normalized_national_number);
1253
if (HasPrefixString(normalized_national_number, national_prefix)) {
1254
// Some Japanese numbers (e.g. 00777123) might be mistaken to contain
1255
// the national prefix when written without it (e.g. 0777123) if we just
1256
// do prefix matching. To tackle that, we check the validity of the
1257
// number if the assumed national prefix is removed (777123 won't be
1259
PhoneNumber number_without_national_prefix;
1260
if (Parse(normalized_national_number.substr(national_prefix.length()),
1261
region_code, &number_without_national_prefix)
1262
== NO_PARSING_ERROR) {
1263
return IsValidNumber(number_without_national_prefix);
1269
bool PhoneNumberUtil::HasUnexpectedItalianLeadingZero(
1270
const PhoneNumber& number) const {
1271
return number.has_italian_leading_zero() &&
1272
!IsLeadingZeroPossible(number.country_code());
1275
bool PhoneNumberUtil::HasFormattingPatternForNumber(
1276
const PhoneNumber& number) const {
1277
int country_calling_code = number.country_code();
1279
GetRegionCodeForCountryCode(country_calling_code, ®ion_code);
1280
const PhoneMetadata* metadata =
1281
GetMetadataForRegionOrCallingCode(country_calling_code, region_code);
1285
string national_number;
1286
GetNationalSignificantNumber(number, &national_number);
1287
const NumberFormat* format_rule =
1288
ChooseFormattingPatternForNumber(metadata->number_format(),
1293
void PhoneNumberUtil::FormatOutOfCountryKeepingAlphaChars(
1294
const PhoneNumber& number,
1295
const string& calling_from,
1296
string* formatted_number) const {
1297
// If there is no raw input, then we can't keep alpha characters because there
1298
// aren't any. In this case, we return FormatOutOfCountryCallingNumber.
1299
if (number.raw_input().empty()) {
1300
FormatOutOfCountryCallingNumber(number, calling_from, formatted_number);
1303
int country_code = number.country_code();
1304
if (!HasValidCountryCallingCode(country_code)) {
1305
formatted_number->assign(number.raw_input());
1308
// Strip any prefix such as country calling code, IDD, that was present. We do
1309
// this by comparing the number in raw_input with the parsed number.
1310
string raw_input_copy(number.raw_input());
1311
// Normalize punctuation. We retain number grouping symbols such as " " only.
1312
NormalizeHelper(reg_exps_->all_plus_number_grouping_symbols_, true,
1314
// Now we trim everything before the first three digits in the parsed number.
1315
// We choose three because all valid alpha numbers have 3 digits at the start
1316
// - if it does not, then we don't trim anything at all. Similarly, if the
1317
// national number was less than three digits, we don't trim anything at all.
1318
string national_number;
1319
GetNationalSignificantNumber(number, &national_number);
1320
if (national_number.length() > 3) {
1321
size_t first_national_number_digit =
1322
raw_input_copy.find(national_number.substr(0, 3));
1323
if (first_national_number_digit != string::npos) {
1324
raw_input_copy = raw_input_copy.substr(first_national_number_digit);
1327
const PhoneMetadata* metadata = GetMetadataForRegion(calling_from);
1328
if (country_code == kNanpaCountryCode) {
1329
if (IsNANPACountry(calling_from)) {
1330
StrAppend(formatted_number, country_code, " ", raw_input_copy);
1333
} else if (metadata &&
1334
country_code == GetCountryCodeForValidRegion(calling_from)) {
1335
const NumberFormat* formatting_pattern =
1336
ChooseFormattingPatternForNumber(metadata->number_format(),
1338
if (!formatting_pattern) {
1339
// If no pattern above is matched, we format the original input.
1340
formatted_number->assign(raw_input_copy);
1343
NumberFormat new_format;
1344
new_format.MergeFrom(*formatting_pattern);
1345
// The first group is the first group of digits that the user wrote
1347
new_format.set_pattern("(\\d+)(.*)");
1348
// Here we just concatenate them back together after the national prefix
1350
new_format.set_format("$1$2");
1351
// Now we format using this pattern instead of the default pattern, but
1352
// with the national prefix prefixed if necessary.
1353
// This will not work in the cases where the pattern (and not the
1354
// leading digits) decide whether a national prefix needs to be used, since
1355
// we have overridden the pattern to match anything, but that is not the
1356
// case in the metadata to date.
1357
FormatNsnUsingPattern(raw_input_copy, new_format, NATIONAL,
1362
string international_prefix_for_formatting;
1363
// If an unsupported region-calling-from is entered, or a country with
1364
// multiple international prefixes, the international format of the number is
1365
// returned, unless there is a preferred international prefix.
1367
const string& international_prefix = metadata->international_prefix();
1368
international_prefix_for_formatting =
1369
reg_exps_->unique_international_prefix_->FullMatch(international_prefix)
1370
? international_prefix
1371
: metadata->preferred_international_prefix();
1373
if (!international_prefix_for_formatting.empty()) {
1374
StrAppend(formatted_number, international_prefix_for_formatting, " ",
1375
country_code, " ", raw_input_copy);
1377
// Invalid region entered as country-calling-from (so no metadata was found
1378
// for it) or the region chosen has multiple international dialling
1380
LOG(WARNING) << "Trying to format number from invalid region "
1382
<< ". International formatting applied.";
1383
formatted_number->assign(raw_input_copy);
1384
PrefixNumberWithCountryCallingCode(country_code, INTERNATIONAL,
1389
const NumberFormat* PhoneNumberUtil::ChooseFormattingPatternForNumber(
1390
const RepeatedPtrField<NumberFormat>& available_formats,
1391
const string& national_number) const {
1392
for (RepeatedPtrField<NumberFormat>::const_iterator
1393
it = available_formats.begin(); it != available_formats.end(); ++it) {
1394
int size = it->leading_digits_pattern_size();
1396
const scoped_ptr<RegExpInput> number_copy(
1397
reg_exps_->regexp_factory_->CreateInput(national_number));
1398
// We always use the last leading_digits_pattern, as it is the most
1400
if (!reg_exps_->regexp_cache_->GetRegExp(
1401
it->leading_digits_pattern(size - 1)).Consume(
1402
number_copy.get())) {
1406
const RegExp& pattern_to_match(
1407
reg_exps_->regexp_cache_->GetRegExp(it->pattern()));
1408
if (pattern_to_match.FullMatch(national_number)) {
1415
// Note that carrier_code is optional - if an empty string, no carrier code
1416
// replacement will take place.
1417
void PhoneNumberUtil::FormatNsnUsingPatternWithCarrier(
1418
const string& national_number,
1419
const NumberFormat& formatting_pattern,
1420
PhoneNumberUtil::PhoneNumberFormat number_format,
1421
const string& carrier_code,
1422
string* formatted_number) const {
1423
DCHECK(formatted_number);
1424
string number_format_rule(formatting_pattern.format());
1425
if (number_format == PhoneNumberUtil::NATIONAL &&
1426
carrier_code.length() > 0 &&
1427
formatting_pattern.domestic_carrier_code_formatting_rule().length() > 0) {
1428
// Replace the $CC in the formatting rule with the desired carrier code.
1429
string carrier_code_formatting_rule =
1430
formatting_pattern.domestic_carrier_code_formatting_rule();
1431
reg_exps_->carrier_code_pattern_->Replace(&carrier_code_formatting_rule,
1433
reg_exps_->first_group_capturing_pattern_->
1434
Replace(&number_format_rule, carrier_code_formatting_rule);
1436
// Use the national prefix formatting rule instead.
1437
string national_prefix_formatting_rule =
1438
formatting_pattern.national_prefix_formatting_rule();
1439
if (number_format == PhoneNumberUtil::NATIONAL &&
1440
national_prefix_formatting_rule.length() > 0) {
1441
// Apply the national_prefix_formatting_rule as the formatting_pattern
1442
// contains only information on how the national significant number
1443
// should be formatted at this point.
1444
reg_exps_->first_group_capturing_pattern_->Replace(
1445
&number_format_rule, national_prefix_formatting_rule);
1448
formatted_number->assign(national_number);
1450
const RegExp& pattern_to_match(
1451
reg_exps_->regexp_cache_->GetRegExp(formatting_pattern.pattern()));
1452
pattern_to_match.GlobalReplace(formatted_number, number_format_rule);
1454
if (number_format == RFC3966) {
1455
// First consume any leading punctuation, if any was present.
1456
const scoped_ptr<RegExpInput> number(
1457
reg_exps_->regexp_factory_->CreateInput(*formatted_number));
1458
if (reg_exps_->separator_pattern_->Consume(number.get())) {
1459
formatted_number->assign(number->ToString());
1461
// Then replace all separators with a "-".
1462
reg_exps_->separator_pattern_->GlobalReplace(formatted_number, "-");
1466
// Simple wrapper of FormatNsnUsingPatternWithCarrier for the common case of
1468
void PhoneNumberUtil::FormatNsnUsingPattern(
1469
const string& national_number,
1470
const NumberFormat& formatting_pattern,
1471
PhoneNumberUtil::PhoneNumberFormat number_format,
1472
string* formatted_number) const {
1473
DCHECK(formatted_number);
1474
FormatNsnUsingPatternWithCarrier(national_number, formatting_pattern,
1475
number_format, "", formatted_number);
1478
void PhoneNumberUtil::FormatNsn(const string& number,
1479
const PhoneMetadata& metadata,
1480
PhoneNumberFormat number_format,
1481
string* formatted_number) const {
1482
DCHECK(formatted_number);
1483
FormatNsnWithCarrier(number, metadata, number_format, "", formatted_number);
1486
// Note in some regions, the national number can be written in two completely
1487
// different ways depending on whether it forms part of the NATIONAL format or
1488
// INTERNATIONAL format. The number_format parameter here is used to specify
1489
// which format to use for those cases. If a carrier_code is specified, this
1490
// will be inserted into the formatted string to replace $CC.
1491
void PhoneNumberUtil::FormatNsnWithCarrier(const string& number,
1492
const PhoneMetadata& metadata,
1493
PhoneNumberFormat number_format,
1494
const string& carrier_code,
1495
string* formatted_number) const {
1496
DCHECK(formatted_number);
1497
// When the intl_number_formats exists, we use that to format national number
1498
// for the INTERNATIONAL format instead of using the number_formats.
1499
const RepeatedPtrField<NumberFormat> available_formats =
1500
(metadata.intl_number_format_size() == 0 || number_format == NATIONAL)
1501
? metadata.number_format()
1502
: metadata.intl_number_format();
1503
const NumberFormat* formatting_pattern =
1504
ChooseFormattingPatternForNumber(available_formats, number);
1505
if (!formatting_pattern) {
1506
formatted_number->assign(number);
1508
FormatNsnUsingPatternWithCarrier(number, *formatting_pattern, number_format,
1509
carrier_code, formatted_number);
1513
// Appends the formatted extension of a phone number, if the phone number had an
1514
// extension specified.
1515
void PhoneNumberUtil::MaybeAppendFormattedExtension(
1516
const PhoneNumber& number,
1517
const PhoneMetadata& metadata,
1518
PhoneNumberFormat number_format,
1519
string* formatted_number) const {
1520
DCHECK(formatted_number);
1521
if (number.has_extension() && number.extension().length() > 0) {
1522
if (number_format == RFC3966) {
1523
StrAppend(formatted_number, kRfc3966ExtnPrefix, number.extension());
1525
if (metadata.has_preferred_extn_prefix()) {
1526
StrAppend(formatted_number, metadata.preferred_extn_prefix(),
1527
number.extension());
1529
StrAppend(formatted_number, kDefaultExtnPrefix, number.extension());
1535
bool PhoneNumberUtil::IsNANPACountry(const string& region_code) const {
1536
return nanpa_regions_->find(region_code) != nanpa_regions_->end();
1539
// Returns the region codes that matches the specific country calling code. In
1540
// the case of no region code being found, region_codes will be left empty.
1541
void PhoneNumberUtil::GetRegionCodesForCountryCallingCode(
1542
int country_calling_code,
1543
list<string>* region_codes) const {
1544
DCHECK(region_codes);
1545
// Create a IntRegionsPair with the country_code passed in, and use it to
1546
// locate the pair with the same country_code in the sorted vector.
1547
IntRegionsPair target_pair;
1548
target_pair.first = country_calling_code;
1549
typedef vector<IntRegionsPair>::const_iterator ConstIterator;
1550
pair<ConstIterator, ConstIterator> range = equal_range(
1551
country_calling_code_to_region_code_map_->begin(),
1552
country_calling_code_to_region_code_map_->end(),
1553
target_pair, OrderByFirst());
1554
if (range.first != range.second) {
1555
region_codes->insert(region_codes->begin(),
1556
range.first->second->begin(),
1557
range.first->second->end());
1561
// Returns the region code that matches the specific country calling code. In
1562
// the case of no region code being found, the unknown region code will be
1564
void PhoneNumberUtil::GetRegionCodeForCountryCode(
1565
int country_calling_code,
1566
string* region_code) const {
1567
DCHECK(region_code);
1568
list<string> region_codes;
1570
GetRegionCodesForCountryCallingCode(country_calling_code, ®ion_codes);
1571
*region_code = (region_codes.size() > 0) ?
1572
region_codes.front() : RegionCode::GetUnknown();
1575
void PhoneNumberUtil::GetRegionCodeForNumber(const PhoneNumber& number,
1576
string* region_code) const {
1577
DCHECK(region_code);
1578
int country_calling_code = number.country_code();
1579
list<string> region_codes;
1580
GetRegionCodesForCountryCallingCode(country_calling_code, ®ion_codes);
1581
if (region_codes.size() == 0) {
1582
string number_string;
1583
GetNationalSignificantNumber(number, &number_string);
1584
VLOG(1) << "Missing/invalid country calling code ("
1585
<< country_calling_code
1586
<< ") for number " << number_string;
1587
*region_code = RegionCode::GetUnknown();
1590
if (region_codes.size() == 1) {
1591
*region_code = region_codes.front();
1593
GetRegionCodeForNumberFromRegionList(number, region_codes, region_code);
1597
void PhoneNumberUtil::GetRegionCodeForNumberFromRegionList(
1598
const PhoneNumber& number, const list<string>& region_codes,
1599
string* region_code) const {
1600
DCHECK(region_code);
1601
string national_number;
1602
GetNationalSignificantNumber(number, &national_number);
1603
for (list<string>::const_iterator it = region_codes.begin();
1604
it != region_codes.end(); ++it) {
1605
// Metadata cannot be NULL because the region codes come from the country
1606
// calling code map.
1607
const PhoneMetadata* metadata = GetMetadataForRegion(*it);
1608
if (metadata->has_leading_digits()) {
1609
const scoped_ptr<RegExpInput> number(
1610
reg_exps_->regexp_factory_->CreateInput(national_number));
1611
if (reg_exps_->regexp_cache_->
1612
GetRegExp(metadata->leading_digits()).Consume(number.get())) {
1616
} else if (GetNumberTypeHelper(national_number, *metadata) != UNKNOWN) {
1621
*region_code = RegionCode::GetUnknown();
1624
int PhoneNumberUtil::GetCountryCodeForRegion(const string& region_code) const {
1625
if (!IsValidRegionCode(region_code)) {
1626
LOG(WARNING) << "Invalid or unknown region code (" << region_code
1630
return GetCountryCodeForValidRegion(region_code);
1633
int PhoneNumberUtil::GetCountryCodeForValidRegion(
1634
const string& region_code) const {
1635
const PhoneMetadata* metadata = GetMetadataForRegion(region_code);
1636
return metadata->country_code();
1639
// Gets a valid fixed-line number for the specified region_code. Returns false
1640
// if the region was unknown or 001 (representing non-geographical regions), or
1641
// if no number exists.
1642
bool PhoneNumberUtil::GetExampleNumber(const string& region_code,
1643
PhoneNumber* number) const {
1645
return GetExampleNumberForType(region_code, FIXED_LINE, number);
1648
// Gets a valid number for the specified region_code and type. Returns false if
1649
// the country was unknown or 001 (representing non-geographical regions), or if
1650
// no number exists.
1651
bool PhoneNumberUtil::GetExampleNumberForType(
1652
const string& region_code,
1653
PhoneNumberUtil::PhoneNumberType type,
1654
PhoneNumber* number) const {
1656
if (!IsValidRegionCode(region_code)) {
1657
LOG(WARNING) << "Invalid or unknown region code (" << region_code
1661
const PhoneMetadata* region_metadata = GetMetadataForRegion(region_code);
1662
const PhoneNumberDesc* desc = GetNumberDescByType(*region_metadata, type);
1663
if (desc && desc->has_example_number()) {
1664
ErrorType success = Parse(desc->example_number(), region_code, number);
1665
if (success == NO_PARSING_ERROR) {
1668
LOG(ERROR) << "Error parsing example number ("
1669
<< static_cast<int>(success) << ")";
1675
bool PhoneNumberUtil::GetExampleNumberForNonGeoEntity(
1676
int country_calling_code, PhoneNumber* number) const {
1678
const PhoneMetadata* metadata =
1679
GetMetadataForNonGeographicalRegion(country_calling_code);
1681
const PhoneNumberDesc& desc = metadata->general_desc();
1682
if (desc.has_example_number()) {
1683
ErrorType success = Parse(StrCat(kPlusSign,
1684
SimpleItoa(country_calling_code),
1685
desc.example_number()),
1686
RegionCode::ZZ(), number);
1687
if (success == NO_PARSING_ERROR) {
1690
LOG(ERROR) << "Error parsing example number ("
1691
<< static_cast<int>(success) << ")";
1695
LOG(WARNING) << "Invalid or unknown country calling code provided: "
1696
<< country_calling_code;
1701
PhoneNumberUtil::ErrorType PhoneNumberUtil::Parse(const string& number_to_parse,
1702
const string& default_region,
1703
PhoneNumber* number) const {
1705
return ParseHelper(number_to_parse, default_region, false, true, number);
1708
PhoneNumberUtil::ErrorType PhoneNumberUtil::ParseAndKeepRawInput(
1709
const string& number_to_parse,
1710
const string& default_region,
1711
PhoneNumber* number) const {
1713
return ParseHelper(number_to_parse, default_region, true, true, number);
1716
// Checks to see that the region code used is valid, or if it is not valid, that
1717
// the number to parse starts with a + symbol so that we can attempt to infer
1718
// the country from the number. Returns false if it cannot use the region
1719
// provided and the region cannot be inferred.
1720
bool PhoneNumberUtil::CheckRegionForParsing(
1721
const string& number_to_parse,
1722
const string& default_region) const {
1723
if (!IsValidRegionCode(default_region) && !number_to_parse.empty()) {
1724
const scoped_ptr<RegExpInput> number(
1725
reg_exps_->regexp_factory_->CreateInput(number_to_parse));
1726
if (!reg_exps_->plus_chars_pattern_->Consume(number.get())) {
1733
// Converts number_to_parse to a form that we can parse and write it to
1734
// national_number if it is written in RFC3966; otherwise extract a possible
1735
// number out of it and write to national_number.
1736
void PhoneNumberUtil::BuildNationalNumberForParsing(
1737
const string& number_to_parse, string* national_number) const {
1738
size_t index_of_phone_context = number_to_parse.find(kRfc3966PhoneContext);
1739
if (index_of_phone_context != string::npos) {
1740
int phone_context_start =
1741
index_of_phone_context + strlen(kRfc3966PhoneContext);
1742
// If the phone context contains a phone number prefix, we need to capture
1743
// it, whereas domains will be ignored.
1744
if (number_to_parse.at(phone_context_start) == kPlusSign[0]) {
1745
// Additional parameters might follow the phone context. If so, we will
1746
// remove them here because the parameters after phone context are not
1747
// important for parsing the phone number.
1748
size_t phone_context_end = number_to_parse.find(';', phone_context_start);
1749
if (phone_context_end != string::npos) {
1751
national_number, number_to_parse.substr(
1752
phone_context_start, phone_context_end - phone_context_start));
1754
StrAppend(national_number, number_to_parse.substr(phone_context_start));
1758
// Now append everything between the "tel:" prefix and the phone-context.
1759
// This should include the national number, an optional extension or
1760
// isdn-subaddress component. Note we also handle the case when "tel:" is
1761
// missing, as we have seen in some of the phone number inputs. In that
1762
// case, we append everything from the beginning.
1763
size_t index_of_rfc_prefix = number_to_parse.find(kRfc3966Prefix);
1764
int index_of_national_number = (index_of_rfc_prefix != string::npos) ?
1765
index_of_rfc_prefix + strlen(kRfc3966Prefix) : 0;
1768
number_to_parse.substr(
1769
index_of_national_number,
1770
index_of_phone_context - index_of_national_number));
1772
// Extract a possible number from the string passed in (this strips leading
1773
// characters that could not be the start of a phone number.)
1774
ExtractPossibleNumber(number_to_parse, national_number);
1777
// Delete the isdn-subaddress and everything after it if it is present. Note
1778
// extension won't appear at the same time with isdn-subaddress according to
1779
// paragraph 5.3 of the RFC3966 spec.
1780
size_t index_of_isdn = national_number->find(kRfc3966IsdnSubaddress);
1781
if (index_of_isdn != string::npos) {
1782
national_number->erase(index_of_isdn);
1784
// If both phone context and isdn-subaddress are absent but other parameters
1785
// are present, the parameters are left in nationalNumber. This is because
1786
// we are concerned about deleting content from a potential number string
1787
// when there is no strong evidence that the number is actually written in
1791
PhoneNumberUtil::ErrorType PhoneNumberUtil::ParseHelper(
1792
const string& number_to_parse,
1793
const string& default_region,
1794
bool keep_raw_input,
1796
PhoneNumber* phone_number) const {
1797
DCHECK(phone_number);
1799
string national_number;
1800
BuildNationalNumberForParsing(number_to_parse, &national_number);
1802
if (!IsViablePhoneNumber(national_number)) {
1803
VLOG(2) << "The string supplied did not seem to be a phone number.";
1804
return NOT_A_NUMBER;
1808
!CheckRegionForParsing(national_number, default_region)) {
1809
VLOG(1) << "Missing or invalid default country.";
1810
return INVALID_COUNTRY_CODE_ERROR;
1812
PhoneNumber temp_number;
1813
if (keep_raw_input) {
1814
temp_number.set_raw_input(number_to_parse);
1816
// Attempt to parse extension first, since it doesn't require country-specific
1817
// data and we want to have the non-normalised number here.
1819
MaybeStripExtension(&national_number, &extension);
1820
if (!extension.empty()) {
1821
temp_number.set_extension(extension);
1823
const PhoneMetadata* country_metadata = GetMetadataForRegion(default_region);
1824
// Check to see if the number is given in international format so we know
1825
// whether this number is from the default country or not.
1826
string normalized_national_number(national_number);
1827
ErrorType country_code_error =
1828
MaybeExtractCountryCode(country_metadata, keep_raw_input,
1829
&normalized_national_number, &temp_number);
1830
if (country_code_error != NO_PARSING_ERROR) {
1831
const scoped_ptr<RegExpInput> number_string_piece(
1832
reg_exps_->regexp_factory_->CreateInput(national_number));
1833
if ((country_code_error == INVALID_COUNTRY_CODE_ERROR) &&
1834
(reg_exps_->plus_chars_pattern_->Consume(number_string_piece.get()))) {
1835
normalized_national_number.assign(number_string_piece->ToString());
1836
// Strip the plus-char, and try again.
1837
MaybeExtractCountryCode(country_metadata,
1839
&normalized_national_number,
1841
if (temp_number.country_code() == 0) {
1842
return INVALID_COUNTRY_CODE_ERROR;
1845
return country_code_error;
1848
int country_code = temp_number.country_code();
1849
if (country_code != 0) {
1850
string phone_number_region;
1851
GetRegionCodeForCountryCode(country_code, &phone_number_region);
1852
if (phone_number_region != default_region) {
1854
GetMetadataForRegionOrCallingCode(country_code, phone_number_region);
1856
} else if (country_metadata) {
1857
// If no extracted country calling code, use the region supplied instead.
1858
// Note that the national number was already normalized by
1859
// MaybeExtractCountryCode.
1860
country_code = country_metadata->country_code();
1862
if (normalized_national_number.length() < kMinLengthForNsn) {
1863
VLOG(2) << "The string supplied is too short to be a phone number.";
1864
return TOO_SHORT_NSN;
1866
if (country_metadata) {
1867
string carrier_code;
1868
string potential_national_number(normalized_national_number);
1869
MaybeStripNationalPrefixAndCarrierCode(*country_metadata,
1870
&potential_national_number,
1872
// We require that the NSN remaining after stripping the national prefix
1873
// and carrier code be of a possible length for the region. Otherwise, we
1874
// don't do the stripping, since the original number could be a valid short
1876
if (!IsShorterThanPossibleNormalNumber(country_metadata,
1877
potential_national_number)) {
1878
normalized_national_number.assign(potential_national_number);
1879
if (keep_raw_input) {
1880
temp_number.set_preferred_domestic_carrier_code(carrier_code);
1884
size_t normalized_national_number_length =
1885
normalized_national_number.length();
1886
if (normalized_national_number_length < kMinLengthForNsn) {
1887
VLOG(2) << "The string supplied is too short to be a phone number.";
1888
return TOO_SHORT_NSN;
1890
if (normalized_national_number_length > kMaxLengthForNsn) {
1891
VLOG(2) << "The string supplied is too long to be a phone number.";
1892
return TOO_LONG_NSN;
1894
temp_number.set_country_code(country_code);
1895
SetItalianLeadingZerosForPhoneNumber(normalized_national_number,
1897
uint64 number_as_int;
1898
safe_strtou64(normalized_national_number, &number_as_int);
1899
temp_number.set_national_number(number_as_int);
1900
phone_number->Swap(&temp_number);
1901
return NO_PARSING_ERROR;
1904
// Attempts to extract a possible number from the string passed in. This
1905
// currently strips all leading characters that could not be used to start a
1906
// phone number. Characters that can be used to start a phone number are
1907
// defined in the valid_start_char_pattern. If none of these characters are
1908
// found in the number passed in, an empty string is returned. This function
1909
// also attempts to strip off any alternative extensions or endings if two or
1910
// more are present, such as in the case of: (530) 583-6985 x302/x2303. The
1911
// second extension here makes this actually two phone numbers, (530) 583-6985
1912
// x302 and (530) 583-6985 x2303. We remove the second extension so that the
1913
// first number is parsed correctly.
1914
void PhoneNumberUtil::ExtractPossibleNumber(const string& number,
1915
string* extracted_number) const {
1916
DCHECK(extracted_number);
1918
UnicodeText number_as_unicode;
1919
number_as_unicode.PointToUTF8(number.data(), number.size());
1920
char current_char[5];
1922
UnicodeText::const_iterator it;
1923
for (it = number_as_unicode.begin(); it != number_as_unicode.end(); ++it) {
1924
len = it.get_utf8(current_char);
1925
current_char[len] = '\0';
1926
if (reg_exps_->valid_start_char_pattern_->FullMatch(current_char)) {
1931
if (it == number_as_unicode.end()) {
1932
// No valid start character was found. extracted_number should be set to
1934
extracted_number->assign("");
1938
extracted_number->assign(
1939
UnicodeText::UTF8Substring(it, number_as_unicode.end()));
1940
TrimUnwantedEndChars(extracted_number);
1941
if (extracted_number->length() == 0) {
1945
VLOG(3) << "After stripping starting and trailing characters, left with: "
1946
<< *extracted_number;
1948
// Now remove any extra numbers at the end.
1949
reg_exps_->capture_up_to_second_number_start_pattern_->
1950
PartialMatch(*extracted_number, extracted_number);
1953
bool PhoneNumberUtil::IsPossibleNumber(const PhoneNumber& number) const {
1954
return IsPossibleNumberWithReason(number) == IS_POSSIBLE;
1957
bool PhoneNumberUtil::IsPossibleNumberForString(
1958
const string& number,
1959
const string& region_dialing_from) const {
1960
PhoneNumber number_proto;
1961
if (Parse(number, region_dialing_from, &number_proto) == NO_PARSING_ERROR) {
1962
return IsPossibleNumber(number_proto);
1968
PhoneNumberUtil::ValidationResult PhoneNumberUtil::IsPossibleNumberWithReason(
1969
const PhoneNumber& number) const {
1970
string national_number;
1971
GetNationalSignificantNumber(number, &national_number);
1972
int country_code = number.country_code();
1973
// Note: For Russian Fed and NANPA numbers, we just use the rules from the
1974
// default region (US or Russia) since the GetRegionCodeForNumber will not
1975
// work if the number is possible but not valid. This would need to be
1976
// revisited if the possible number pattern ever differed between various
1977
// regions within those plans.
1978
if (!HasValidCountryCallingCode(country_code)) {
1979
return INVALID_COUNTRY_CODE;
1982
GetRegionCodeForCountryCode(country_code, ®ion_code);
1983
// Metadata cannot be NULL because the country calling code is valid.
1984
const PhoneMetadata* metadata =
1985
GetMetadataForRegionOrCallingCode(country_code, region_code);
1986
const RegExp& possible_number_pattern = reg_exps_->regexp_cache_->GetRegExp(
1987
StrCat("(", metadata->general_desc().possible_number_pattern(), ")"));
1988
return TestNumberLengthAgainstPattern(possible_number_pattern,
1992
bool PhoneNumberUtil::TruncateTooLongNumber(PhoneNumber* number) const {
1993
if (IsValidNumber(*number)) {
1996
PhoneNumber number_copy(*number);
1997
uint64 national_number = number->national_number();
1999
national_number /= 10;
2000
number_copy.set_national_number(national_number);
2001
if (IsPossibleNumberWithReason(number_copy) == TOO_SHORT ||
2002
national_number == 0) {
2005
} while (!IsValidNumber(number_copy));
2006
number->set_national_number(national_number);
2010
PhoneNumberUtil::PhoneNumberType PhoneNumberUtil::GetNumberType(
2011
const PhoneNumber& number) const {
2013
GetRegionCodeForNumber(number, ®ion_code);
2014
const PhoneMetadata* metadata =
2015
GetMetadataForRegionOrCallingCode(number.country_code(), region_code);
2019
string national_significant_number;
2020
GetNationalSignificantNumber(number, &national_significant_number);
2021
return GetNumberTypeHelper(national_significant_number, *metadata);
2024
bool PhoneNumberUtil::IsValidNumber(const PhoneNumber& number) const {
2026
GetRegionCodeForNumber(number, ®ion_code);
2027
return IsValidNumberForRegion(number, region_code);
2030
bool PhoneNumberUtil::IsValidNumberForRegion(const PhoneNumber& number,
2031
const string& region_code) const {
2032
int country_code = number.country_code();
2033
const PhoneMetadata* metadata =
2034
GetMetadataForRegionOrCallingCode(country_code, region_code);
2036
((kRegionCodeForNonGeoEntity != region_code) &&
2037
country_code != GetCountryCodeForValidRegion(region_code))) {
2038
// Either the region code was invalid, or the country calling code for this
2039
// number does not match that of the region code.
2042
string national_number;
2043
GetNationalSignificantNumber(number, &national_number);
2045
return GetNumberTypeHelper(national_number, *metadata) != UNKNOWN;
2048
bool PhoneNumberUtil::IsNumberGeographical(
2049
const PhoneNumber& phone_number) const {
2050
PhoneNumberType number_type = GetNumberType(phone_number);
2051
// TODO: Include mobile phone numbers from countries like
2052
// Indonesia, which has some mobile numbers that are geographical.
2053
return number_type == PhoneNumberUtil::FIXED_LINE ||
2054
number_type == PhoneNumberUtil::FIXED_LINE_OR_MOBILE;
2057
bool PhoneNumberUtil::IsLeadingZeroPossible(int country_calling_code) const {
2059
GetRegionCodeForCountryCode(country_calling_code, ®ion_code);
2060
const PhoneMetadata* main_metadata_for_calling_code =
2061
GetMetadataForRegionOrCallingCode(country_calling_code, region_code);
2062
if (!main_metadata_for_calling_code) return false;
2063
return main_metadata_for_calling_code->leading_zero_possible();
2066
// A helper function to set the values related to leading zeros in a
2068
void PhoneNumberUtil::SetItalianLeadingZerosForPhoneNumber(
2069
const string& national_number, PhoneNumber* phone_number) const {
2070
if (national_number.length() > 1 && national_number[0] == '0') {
2071
phone_number->set_italian_leading_zero(true);
2072
size_t number_of_leading_zeros = 1;
2073
// Note that if the national number is all "0"s, the last "0" is not
2074
// counted as a leading zero.
2075
while (number_of_leading_zeros < national_number.length() - 1 &&
2076
national_number[number_of_leading_zeros] == '0') {
2077
number_of_leading_zeros++;
2079
if (number_of_leading_zeros != 1) {
2080
phone_number->set_number_of_leading_zeros(number_of_leading_zeros);
2085
bool PhoneNumberUtil::IsNumberPossibleForDesc(
2086
const string& national_number, const PhoneNumberDesc& number_desc) const {
2087
return reg_exps_->regexp_cache_.get()->
2088
GetRegExp(number_desc.possible_number_pattern())
2089
.FullMatch(national_number);
2092
bool PhoneNumberUtil::IsNumberMatchingDesc(
2093
const string& national_number, const PhoneNumberDesc& number_desc) const {
2094
return IsNumberPossibleForDesc(national_number, number_desc) &&
2095
reg_exps_->regexp_cache_.get()->
2096
GetRegExp(number_desc.national_number_pattern())
2097
.FullMatch(national_number);
2100
PhoneNumberUtil::PhoneNumberType PhoneNumberUtil::GetNumberTypeHelper(
2101
const string& national_number, const PhoneMetadata& metadata) const {
2102
if (!IsNumberMatchingDesc(national_number, metadata.general_desc())) {
2103
VLOG(4) << "Number type unknown - doesn't match general national number"
2105
return PhoneNumberUtil::UNKNOWN;
2107
if (IsNumberMatchingDesc(national_number, metadata.premium_rate())) {
2108
VLOG(4) << "Number is a premium number.";
2109
return PhoneNumberUtil::PREMIUM_RATE;
2111
if (IsNumberMatchingDesc(national_number, metadata.toll_free())) {
2112
VLOG(4) << "Number is a toll-free number.";
2113
return PhoneNumberUtil::TOLL_FREE;
2115
if (IsNumberMatchingDesc(national_number, metadata.shared_cost())) {
2116
VLOG(4) << "Number is a shared cost number.";
2117
return PhoneNumberUtil::SHARED_COST;
2119
if (IsNumberMatchingDesc(national_number, metadata.voip())) {
2120
VLOG(4) << "Number is a VOIP (Voice over IP) number.";
2121
return PhoneNumberUtil::VOIP;
2123
if (IsNumberMatchingDesc(national_number, metadata.personal_number())) {
2124
VLOG(4) << "Number is a personal number.";
2125
return PhoneNumberUtil::PERSONAL_NUMBER;
2127
if (IsNumberMatchingDesc(national_number, metadata.pager())) {
2128
VLOG(4) << "Number is a pager number.";
2129
return PhoneNumberUtil::PAGER;
2131
if (IsNumberMatchingDesc(national_number, metadata.uan())) {
2132
VLOG(4) << "Number is a UAN.";
2133
return PhoneNumberUtil::UAN;
2135
if (IsNumberMatchingDesc(national_number, metadata.voicemail())) {
2136
VLOG(4) << "Number is a voicemail number.";
2137
return PhoneNumberUtil::VOICEMAIL;
2140
bool is_fixed_line =
2141
IsNumberMatchingDesc(national_number, metadata.fixed_line());
2142
if (is_fixed_line) {
2143
if (metadata.same_mobile_and_fixed_line_pattern()) {
2144
VLOG(4) << "Fixed-line and mobile patterns equal, number is fixed-line"
2146
return PhoneNumberUtil::FIXED_LINE_OR_MOBILE;
2147
} else if (IsNumberMatchingDesc(national_number, metadata.mobile())) {
2148
VLOG(4) << "Fixed-line and mobile patterns differ, but number is "
2149
<< "still fixed-line or mobile";
2150
return PhoneNumberUtil::FIXED_LINE_OR_MOBILE;
2152
VLOG(4) << "Number is a fixed line number.";
2153
return PhoneNumberUtil::FIXED_LINE;
2155
// Otherwise, test to see if the number is mobile. Only do this if certain
2156
// that the patterns for mobile and fixed line aren't the same.
2157
if (!metadata.same_mobile_and_fixed_line_pattern() &&
2158
IsNumberMatchingDesc(national_number, metadata.mobile())) {
2159
VLOG(4) << "Number is a mobile number.";
2160
return PhoneNumberUtil::MOBILE;
2162
VLOG(4) << "Number type unknown - doesn\'t match any specific number type"
2164
return PhoneNumberUtil::UNKNOWN;
2167
void PhoneNumberUtil::GetNationalSignificantNumber(
2168
const PhoneNumber& number,
2169
string* national_number) const {
2170
DCHECK(national_number);
2171
// If leading zero(s) have been set, we prefix this now. Note this is not a
2173
StrAppend(national_number, number.italian_leading_zero() ?
2174
string(number.number_of_leading_zeros(), '0') : "");
2175
StrAppend(national_number, number.national_number());
2178
int PhoneNumberUtil::GetLengthOfGeographicalAreaCode(
2179
const PhoneNumber& number) const {
2181
GetRegionCodeForNumber(number, ®ion_code);
2182
const PhoneMetadata* metadata = GetMetadataForRegion(region_code);
2186
// If a country doesn't use a national prefix, and this number doesn't have an
2187
// Italian leading zero, we assume it is a closed dialling plan with no area
2189
if (!metadata->has_national_prefix() && !number.italian_leading_zero()) {
2193
if (!IsNumberGeographical(number)) {
2197
return GetLengthOfNationalDestinationCode(number);
2200
int PhoneNumberUtil::GetLengthOfNationalDestinationCode(
2201
const PhoneNumber& number) const {
2202
PhoneNumber copied_proto(number);
2203
if (number.has_extension()) {
2204
// Clear the extension so it's not included when formatting.
2205
copied_proto.clear_extension();
2208
string formatted_number;
2209
Format(copied_proto, INTERNATIONAL, &formatted_number);
2210
const scoped_ptr<RegExpInput> i18n_number(
2211
reg_exps_->regexp_factory_->CreateInput(formatted_number));
2215
for (int i = 0; i < 3; ++i) {
2216
if (!reg_exps_->capturing_ascii_digits_pattern_->FindAndConsume(
2217
i18n_number.get(), &digit_group)) {
2218
// We should find at least three groups.
2223
} else if (i == 2) {
2224
third_group = digit_group;
2228
if (GetNumberType(number) == MOBILE) {
2229
// For example Argentinian mobile numbers, when formatted in the
2230
// international format, are in the form of +54 9 NDC XXXX.... As a result,
2231
// we take the length of the third group (NDC) and add the length of the
2232
// mobile token, which also forms part of the national significant number.
2233
// This assumes that the mobile token is always formatted separately from
2234
// the rest of the phone number.
2235
string mobile_token;
2236
GetCountryMobileToken(number.country_code(), &mobile_token);
2237
if (!mobile_token.empty()) {
2238
return third_group.size() + mobile_token.size();
2244
void PhoneNumberUtil::GetCountryMobileToken(int country_calling_code,
2245
string* mobile_token) const {
2246
DCHECK(mobile_token);
2247
map<int, char>::iterator it = reg_exps_->mobile_token_mappings_.find(
2248
country_calling_code);
2249
if (it != reg_exps_->mobile_token_mappings_.end()) {
2250
*mobile_token = it->second;
2252
mobile_token->assign("");
2256
void PhoneNumberUtil::NormalizeDigitsOnly(string* number) const {
2258
const RegExp& non_digits_pattern = reg_exps_->regexp_cache_->GetRegExp(
2259
StrCat("[^", kDigits, "]"));
2260
// Delete everything that isn't valid digits.
2261
non_digits_pattern.GlobalReplace(number, "");
2262
// Normalize all decimal digits to ASCII digits.
2263
number->assign(NormalizeUTF8::NormalizeDecimalDigits(*number));
2266
void PhoneNumberUtil::NormalizeDiallableCharsOnly(string* number) const {
2268
NormalizeHelper(reg_exps_->diallable_char_mappings_,
2269
true /* remove non matches */, number);
2272
bool PhoneNumberUtil::IsAlphaNumber(const string& number) const {
2273
if (!IsViablePhoneNumber(number)) {
2274
// Number is too short, or doesn't match the basic phone number pattern.
2277
// Copy the number, since we are going to try and strip the extension from it.
2278
string number_copy(number);
2280
MaybeStripExtension(&number_copy, &extension);
2281
return reg_exps_->valid_alpha_phone_pattern_->FullMatch(number_copy);
2284
void PhoneNumberUtil::ConvertAlphaCharactersInNumber(string* number) const {
2286
NormalizeHelper(reg_exps_->alpha_phone_mappings_, false, number);
2289
// Normalizes a string of characters representing a phone number. This performs
2290
// the following conversions:
2291
// - Punctuation is stripped.
2292
// For ALPHA/VANITY numbers:
2293
// - Letters are converted to their numeric representation on a telephone
2294
// keypad. The keypad used here is the one defined in ITU Recommendation
2295
// E.161. This is only done if there are 3 or more letters in the number, to
2296
// lessen the risk that such letters are typos.
2297
// For other numbers:
2298
// - Wide-ascii digits are converted to normal ASCII (European) digits.
2299
// - Arabic-Indic numerals are converted to European numerals.
2300
// - Spurious alpha characters are stripped.
2301
void PhoneNumberUtil::Normalize(string* number) const {
2303
if (reg_exps_->valid_alpha_phone_pattern_->PartialMatch(*number)) {
2304
NormalizeHelper(reg_exps_->alpha_phone_mappings_, true, number);
2306
NormalizeDigitsOnly(number);
2309
// Checks to see if the string of characters could possibly be a phone number at
2310
// all. At the moment, checks to see that the string begins with at least 3
2311
// digits, ignoring any punctuation commonly found in phone numbers. This
2312
// method does not require the number to be normalized in advance - but does
2313
// assume that leading non-number symbols have been removed, such as by the
2314
// method ExtractPossibleNumber.
2315
bool PhoneNumberUtil::IsViablePhoneNumber(const string& number) const {
2316
if (number.length() < kMinLengthForNsn) {
2317
VLOG(2) << "Number too short to be viable:" << number;
2320
return reg_exps_->valid_phone_number_pattern_->FullMatch(number);
2323
// Strips the IDD from the start of the number if present. Helper function used
2324
// by MaybeStripInternationalPrefixAndNormalize.
2325
bool PhoneNumberUtil::ParsePrefixAsIdd(const RegExp& idd_pattern,
2326
string* number) const {
2328
const scoped_ptr<RegExpInput> number_copy(
2329
reg_exps_->regexp_factory_->CreateInput(*number));
2330
// First attempt to strip the idd_pattern at the start, if present. We make a
2331
// copy so that we can revert to the original string if necessary.
2332
if (idd_pattern.Consume(number_copy.get())) {
2333
// Only strip this if the first digit after the match is not a 0, since
2334
// country calling codes cannot begin with 0.
2335
string extracted_digit;
2336
if (reg_exps_->capturing_digit_pattern_->PartialMatch(
2337
number_copy->ToString(), &extracted_digit)) {
2338
NormalizeDigitsOnly(&extracted_digit);
2339
if (extracted_digit == "0") {
2343
number->assign(number_copy->ToString());
2349
// Strips any international prefix (such as +, 00, 011) present in the number
2350
// provided, normalizes the resulting number, and indicates if an international
2351
// prefix was present.
2353
// possible_idd_prefix represents the international direct dialing prefix from
2354
// the region we think this number may be dialed in.
2355
// Returns true if an international dialing prefix could be removed from the
2356
// number, otherwise false if the number did not seem to be in international
2358
PhoneNumber::CountryCodeSource
2359
PhoneNumberUtil::MaybeStripInternationalPrefixAndNormalize(
2360
const string& possible_idd_prefix,
2361
string* number) const {
2363
if (number->empty()) {
2364
return PhoneNumber::FROM_DEFAULT_COUNTRY;
2366
const scoped_ptr<RegExpInput> number_string_piece(
2367
reg_exps_->regexp_factory_->CreateInput(*number));
2368
if (reg_exps_->plus_chars_pattern_->Consume(number_string_piece.get())) {
2369
number->assign(number_string_piece->ToString());
2370
// Can now normalize the rest of the number since we've consumed the "+"
2371
// sign at the start.
2373
return PhoneNumber::FROM_NUMBER_WITH_PLUS_SIGN;
2375
// Attempt to parse the first digits as an international prefix.
2376
const RegExp& idd_pattern =
2377
reg_exps_->regexp_cache_->GetRegExp(possible_idd_prefix);
2379
return ParsePrefixAsIdd(idd_pattern, number)
2380
? PhoneNumber::FROM_NUMBER_WITH_IDD
2381
: PhoneNumber::FROM_DEFAULT_COUNTRY;
2384
// Strips any national prefix (such as 0, 1) present in the number provided.
2385
// The number passed in should be the normalized telephone number that we wish
2386
// to strip any national dialing prefix from. The metadata should be for the
2387
// region that we think this number is from. Returns true if a national prefix
2388
// and/or carrier code was stripped.
2389
bool PhoneNumberUtil::MaybeStripNationalPrefixAndCarrierCode(
2390
const PhoneMetadata& metadata,
2392
string* carrier_code) const {
2394
string carrier_code_temp;
2395
const string& possible_national_prefix =
2396
metadata.national_prefix_for_parsing();
2397
if (number->empty() || possible_national_prefix.empty()) {
2398
// Early return for numbers of zero length or with no national prefix
2402
// We use two copies here since Consume modifies the phone number, and if the
2403
// first if-clause fails the number will already be changed.
2404
const scoped_ptr<RegExpInput> number_copy(
2405
reg_exps_->regexp_factory_->CreateInput(*number));
2406
const scoped_ptr<RegExpInput> number_copy_without_transform(
2407
reg_exps_->regexp_factory_->CreateInput(*number));
2408
string number_string_copy(*number);
2409
string captured_part_of_prefix;
2410
const RegExp& national_number_rule = reg_exps_->regexp_cache_->GetRegExp(
2411
metadata.general_desc().national_number_pattern());
2412
// Check if the original number is viable.
2413
bool is_viable_original_number = national_number_rule.FullMatch(*number);
2414
// Attempt to parse the first digits as a national prefix. We make a
2415
// copy so that we can revert to the original string if necessary.
2416
const string& transform_rule = metadata.national_prefix_transform_rule();
2417
const RegExp& possible_national_prefix_pattern =
2418
reg_exps_->regexp_cache_->GetRegExp(possible_national_prefix);
2419
if (!transform_rule.empty() &&
2420
(possible_national_prefix_pattern.Consume(
2421
number_copy.get(), &carrier_code_temp, &captured_part_of_prefix) ||
2422
possible_national_prefix_pattern.Consume(
2423
number_copy.get(), &captured_part_of_prefix)) &&
2424
!captured_part_of_prefix.empty()) {
2425
// If this succeeded, then we must have had a transform rule and there must
2426
// have been some part of the prefix that we captured.
2427
// We make the transformation and check that the resultant number is still
2428
// viable. If so, replace the number and return.
2429
possible_national_prefix_pattern.Replace(&number_string_copy,
2431
if (is_viable_original_number &&
2432
!national_number_rule.FullMatch(number_string_copy)) {
2435
number->assign(number_string_copy);
2437
carrier_code->assign(carrier_code_temp);
2439
} else if (possible_national_prefix_pattern.Consume(
2440
number_copy_without_transform.get(), &carrier_code_temp) ||
2441
possible_national_prefix_pattern.Consume(
2442
number_copy_without_transform.get())) {
2443
VLOG(4) << "Parsed the first digits as a national prefix.";
2444
// If captured_part_of_prefix is empty, this implies nothing was captured by
2445
// the capturing groups in possible_national_prefix; therefore, no
2446
// transformation is necessary, and we just remove the national prefix.
2447
const string number_copy_as_string =
2448
number_copy_without_transform->ToString();
2449
if (is_viable_original_number &&
2450
!national_number_rule.FullMatch(number_copy_as_string)) {
2453
number->assign(number_copy_as_string);
2455
carrier_code->assign(carrier_code_temp);
2459
VLOG(4) << "The first digits did not match the national prefix.";
2464
// Strips any extension (as in, the part of the number dialled after the call is
2465
// connected, usually indicated with extn, ext, x or similar) from the end of
2466
// the number, and returns it. The number passed in should be non-normalized.
2467
bool PhoneNumberUtil::MaybeStripExtension(string* number, string* extension)
2471
// There are three extension capturing groups in the regular expression.
2472
string possible_extension_one;
2473
string possible_extension_two;
2474
string possible_extension_three;
2475
string number_copy(*number);
2476
const scoped_ptr<RegExpInput> number_copy_as_regexp_input(
2477
reg_exps_->regexp_factory_->CreateInput(number_copy));
2478
if (reg_exps_->extn_pattern_->Consume(number_copy_as_regexp_input.get(),
2480
&possible_extension_one,
2481
&possible_extension_two,
2482
&possible_extension_three)) {
2483
// Replace the extensions in the original string here.
2484
reg_exps_->extn_pattern_->Replace(&number_copy, "");
2485
VLOG(4) << "Found an extension. Possible extension one: "
2486
<< possible_extension_one
2487
<< ". Possible extension two: " << possible_extension_two
2488
<< ". Possible extension three: " << possible_extension_three
2489
<< ". Remaining number: " << number_copy;
2490
// If we find a potential extension, and the number preceding this is a
2491
// viable number, we assume it is an extension.
2492
if ((!possible_extension_one.empty() || !possible_extension_two.empty() ||
2493
!possible_extension_three.empty()) &&
2494
IsViablePhoneNumber(number_copy)) {
2495
number->assign(number_copy);
2496
if (!possible_extension_one.empty()) {
2497
extension->assign(possible_extension_one);
2498
} else if (!possible_extension_two.empty()) {
2499
extension->assign(possible_extension_two);
2500
} else if (!possible_extension_three.empty()) {
2501
extension->assign(possible_extension_three);
2509
// Extracts country calling code from national_number, and returns it. It
2510
// assumes that the leading plus sign or IDD has already been removed. Returns 0
2511
// if national_number doesn't start with a valid country calling code, and
2512
// leaves national_number unmodified. Assumes the national_number is at least 3
2514
int PhoneNumberUtil::ExtractCountryCode(string* national_number) const {
2515
int potential_country_code;
2516
if (national_number->empty() || (national_number->at(0) == '0')) {
2517
// Country codes do not begin with a '0'.
2520
for (size_t i = 1; i <= kMaxLengthCountryCode; ++i) {
2521
safe_strto32(national_number->substr(0, i), &potential_country_code);
2523
GetRegionCodeForCountryCode(potential_country_code, ®ion_code);
2524
if (region_code != RegionCode::GetUnknown()) {
2525
national_number->erase(0, i);
2526
return potential_country_code;
2532
// Tries to extract a country calling code from a number. Country calling codes
2533
// are extracted in the following ways:
2534
// - by stripping the international dialing prefix of the region the person
2535
// is dialing from, if this is present in the number, and looking at the next
2537
// - by stripping the '+' sign if present and then looking at the next digits
2538
// - by comparing the start of the number and the country calling code of the
2539
// default region. If the number is not considered possible for the numbering
2540
// plan of the default region initially, but starts with the country calling
2541
// code of this region, validation will be reattempted after stripping this
2542
// country calling code. If this number is considered a possible number, then
2543
// the first digits will be considered the country calling code and removed as
2546
// Returns NO_PARSING_ERROR if a country calling code was successfully
2547
// extracted or none was present, or the appropriate error otherwise, such as
2548
// if a + was present but it was not followed by a valid country calling code.
2549
// If NO_PARSING_ERROR is returned, the national_number without the country
2550
// calling code is populated, and the country_code of the phone_number passed
2551
// in is set to the country calling code if found, otherwise to 0.
2552
PhoneNumberUtil::ErrorType PhoneNumberUtil::MaybeExtractCountryCode(
2553
const PhoneMetadata* default_region_metadata,
2554
bool keep_raw_input,
2555
string* national_number,
2556
PhoneNumber* phone_number) const {
2557
DCHECK(national_number);
2558
DCHECK(phone_number);
2559
// Set the default prefix to be something that will never match if there is no
2561
string possible_country_idd_prefix = default_region_metadata
2562
? default_region_metadata->international_prefix()
2564
PhoneNumber::CountryCodeSource country_code_source =
2565
MaybeStripInternationalPrefixAndNormalize(possible_country_idd_prefix,
2567
if (keep_raw_input) {
2568
phone_number->set_country_code_source(country_code_source);
2570
if (country_code_source != PhoneNumber::FROM_DEFAULT_COUNTRY) {
2571
if (national_number->length() <= kMinLengthForNsn) {
2572
VLOG(2) << "Phone number had an IDD, but after this was not "
2573
<< "long enough to be a viable phone number.";
2574
return TOO_SHORT_AFTER_IDD;
2576
int potential_country_code = ExtractCountryCode(national_number);
2577
if (potential_country_code != 0) {
2578
phone_number->set_country_code(potential_country_code);
2579
return NO_PARSING_ERROR;
2581
// If this fails, they must be using a strange country calling code that we
2582
// don't recognize, or that doesn't exist.
2583
return INVALID_COUNTRY_CODE_ERROR;
2584
} else if (default_region_metadata) {
2585
// Check to see if the number starts with the country calling code for the
2586
// default region. If so, we remove the country calling code, and do some
2587
// checks on the validity of the number before and after.
2588
int default_country_code = default_region_metadata->country_code();
2589
string default_country_code_string(SimpleItoa(default_country_code));
2590
VLOG(4) << "Possible country calling code: " << default_country_code_string;
2591
string potential_national_number;
2592
if (TryStripPrefixString(*national_number,
2593
default_country_code_string,
2594
&potential_national_number)) {
2595
const PhoneNumberDesc& general_num_desc =
2596
default_region_metadata->general_desc();
2597
const RegExp& valid_number_pattern =
2598
reg_exps_->regexp_cache_->GetRegExp(
2599
general_num_desc.national_number_pattern());
2600
MaybeStripNationalPrefixAndCarrierCode(*default_region_metadata,
2601
&potential_national_number,
2603
VLOG(4) << "Number without country calling code prefix: "
2604
<< potential_national_number;
2605
const RegExp& possible_number_pattern =
2606
reg_exps_->regexp_cache_->GetRegExp(
2607
StrCat("(", general_num_desc.possible_number_pattern(), ")"));
2608
// If the number was not valid before but is valid now, or if it was too
2609
// long before, we consider the number with the country code stripped to
2610
// be a better result and keep that instead.
2611
if ((!valid_number_pattern.FullMatch(*national_number) &&
2612
valid_number_pattern.FullMatch(potential_national_number)) ||
2613
TestNumberLengthAgainstPattern(possible_number_pattern,
2614
*national_number) == TOO_LONG) {
2615
national_number->assign(potential_national_number);
2616
if (keep_raw_input) {
2617
phone_number->set_country_code_source(
2618
PhoneNumber::FROM_NUMBER_WITHOUT_PLUS_SIGN);
2620
phone_number->set_country_code(default_country_code);
2621
return NO_PARSING_ERROR;
2625
// No country calling code present. Set the country_code to 0.
2626
phone_number->set_country_code(0);
2627
return NO_PARSING_ERROR;
2630
PhoneNumberUtil::MatchType PhoneNumberUtil::IsNumberMatch(
2631
const PhoneNumber& first_number_in,
2632
const PhoneNumber& second_number_in) const {
2633
// Make copies of the phone number so that the numbers passed in are not
2635
PhoneNumber first_number(first_number_in);
2636
PhoneNumber second_number(second_number_in);
2637
// First clear raw_input and country_code_source and
2638
// preferred_domestic_carrier_code fields and any empty-string extensions so
2639
// that we can use the proto-buffer equality method.
2640
first_number.clear_raw_input();
2641
first_number.clear_country_code_source();
2642
first_number.clear_preferred_domestic_carrier_code();
2643
second_number.clear_raw_input();
2644
second_number.clear_country_code_source();
2645
second_number.clear_preferred_domestic_carrier_code();
2646
if (first_number.extension().empty()) {
2647
first_number.clear_extension();
2649
if (second_number.extension().empty()) {
2650
second_number.clear_extension();
2652
// Early exit if both had extensions and these are different.
2653
if (first_number.has_extension() && second_number.has_extension() &&
2654
first_number.extension() != second_number.extension()) {
2657
int first_number_country_code = first_number.country_code();
2658
int second_number_country_code = second_number.country_code();
2659
// Both had country calling code specified.
2660
if (first_number_country_code != 0 && second_number_country_code != 0) {
2661
if (ExactlySameAs(first_number, second_number)) {
2663
} else if (first_number_country_code == second_number_country_code &&
2664
IsNationalNumberSuffixOfTheOther(first_number, second_number)) {
2665
// A SHORT_NSN_MATCH occurs if there is a difference because of the
2666
// presence or absence of an 'Italian leading zero', the presence or
2667
// absence of an extension, or one NSN being a shorter variant of the
2669
return SHORT_NSN_MATCH;
2671
// This is not a match.
2674
// Checks cases where one or both country calling codes were not specified. To
2675
// make equality checks easier, we first set the country_code fields to be
2677
first_number.set_country_code(second_number_country_code);
2678
// If all else was the same, then this is an NSN_MATCH.
2679
if (ExactlySameAs(first_number, second_number)) {
2682
if (IsNationalNumberSuffixOfTheOther(first_number, second_number)) {
2683
return SHORT_NSN_MATCH;
2688
PhoneNumberUtil::MatchType PhoneNumberUtil::IsNumberMatchWithTwoStrings(
2689
const string& first_number,
2690
const string& second_number) const {
2691
PhoneNumber first_number_as_proto;
2692
ErrorType error_type =
2693
Parse(first_number, RegionCode::GetUnknown(), &first_number_as_proto);
2694
if (error_type == NO_PARSING_ERROR) {
2695
return IsNumberMatchWithOneString(first_number_as_proto, second_number);
2697
if (error_type == INVALID_COUNTRY_CODE_ERROR) {
2698
PhoneNumber second_number_as_proto;
2699
ErrorType error_type = Parse(second_number, RegionCode::GetUnknown(),
2700
&second_number_as_proto);
2701
if (error_type == NO_PARSING_ERROR) {
2702
return IsNumberMatchWithOneString(second_number_as_proto, first_number);
2704
if (error_type == INVALID_COUNTRY_CODE_ERROR) {
2705
error_type = ParseHelper(first_number, RegionCode::GetUnknown(), false,
2706
false, &first_number_as_proto);
2707
if (error_type == NO_PARSING_ERROR) {
2708
error_type = ParseHelper(second_number, RegionCode::GetUnknown(), false,
2709
false, &second_number_as_proto);
2710
if (error_type == NO_PARSING_ERROR) {
2711
return IsNumberMatch(first_number_as_proto, second_number_as_proto);
2716
// One or more of the phone numbers we are trying to match is not a viable
2718
return INVALID_NUMBER;
2721
PhoneNumberUtil::MatchType PhoneNumberUtil::IsNumberMatchWithOneString(
2722
const PhoneNumber& first_number,
2723
const string& second_number) const {
2724
// First see if the second number has an implicit country calling code, by
2725
// attempting to parse it.
2726
PhoneNumber second_number_as_proto;
2727
ErrorType error_type =
2728
Parse(second_number, RegionCode::GetUnknown(), &second_number_as_proto);
2729
if (error_type == NO_PARSING_ERROR) {
2730
return IsNumberMatch(first_number, second_number_as_proto);
2732
if (error_type == INVALID_COUNTRY_CODE_ERROR) {
2733
// The second number has no country calling code. EXACT_MATCH is no longer
2734
// possible. We parse it as if the region was the same as that for the
2735
// first number, and if EXACT_MATCH is returned, we replace this with
2737
string first_number_region;
2738
GetRegionCodeForCountryCode(first_number.country_code(),
2739
&first_number_region);
2740
if (first_number_region != RegionCode::GetUnknown()) {
2741
PhoneNumber second_number_with_first_number_region;
2742
Parse(second_number, first_number_region,
2743
&second_number_with_first_number_region);
2744
MatchType match = IsNumberMatch(first_number,
2745
second_number_with_first_number_region);
2746
if (match == EXACT_MATCH) {
2751
// If the first number didn't have a valid country calling code, then we
2752
// parse the second number without one as well.
2753
error_type = ParseHelper(second_number, RegionCode::GetUnknown(), false,
2754
false, &second_number_as_proto);
2755
if (error_type == NO_PARSING_ERROR) {
2756
return IsNumberMatch(first_number, second_number_as_proto);
2760
// One or more of the phone numbers we are trying to match is not a viable
2762
return INVALID_NUMBER;
2765
AsYouTypeFormatter* PhoneNumberUtil::GetAsYouTypeFormatter(
2766
const string& region_code) const {
2767
return new AsYouTypeFormatter(region_code);
2770
bool PhoneNumberUtil::IsShorterThanPossibleNormalNumber(
2771
const PhoneMetadata* country_metadata, const string& number) const {
2772
const RegExp& possible_number_pattern =
2773
reg_exps_->regexp_cache_->GetRegExp(StrCat("(",
2774
country_metadata->general_desc().possible_number_pattern(), ")"));
2775
return TestNumberLengthAgainstPattern(possible_number_pattern, number) ==
2776
PhoneNumberUtil::TOO_SHORT;
2779
bool PhoneNumberUtil::CanBeInternationallyDialled(
2780
const PhoneNumber& number) const {
2782
GetRegionCodeForNumber(number, ®ion_code);
2783
const PhoneMetadata* metadata = GetMetadataForRegion(region_code);
2785
// Note numbers belonging to non-geographical entities (e.g. +800 numbers)
2786
// are always internationally diallable, and will be caught here.
2789
string national_significant_number;
2790
GetNationalSignificantNumber(number, &national_significant_number);
2791
return !IsNumberMatchingDesc(
2792
national_significant_number, metadata->no_international_dialling());
2795
} // namespace phonenumbers