diff options
author | Shaopeng Jia <shaopengjia@google.com> | 2010-03-23 18:29:45 +0100 |
---|---|---|
committer | Shaopeng Jia <shaopengjia@google.com> | 2010-03-25 11:11:08 +0100 |
commit | 7900ea273b8c33b3c6f70d7dd559127938d0fc3d (patch) | |
tree | f10b150190949c7c81de1084deb9f33d3c04d726 | |
parent | 1524ca8c53cd2c3adee0bb2e2b95a93fee976862 (diff) | |
download | libphonenumber-7900ea273b8c33b3c6f70d7dd559127938d0fc3d.tar.gz |
Update external/libphonenumber from r6 to r9 with the latest functionality, bug-fixes and phone number plan updates.
Details of each revisions see: http://code.google.com/p/libphonenumber/updates/list
Change-Id: Ic38ac4bb84f7b6053011a762a64f591a98f6d9d4
-rw-r--r-- | README.android | 2 | ||||
-rw-r--r-- | java/resources/com/google/i18n/phonenumbers/src/PhoneNumberMetaData.xml | 856 | ||||
-rwxr-xr-x[-rw-r--r--] | java/resources/com/google/i18n/phonenumbers/src/generated_files/PhoneNumberMetadataProto | bin | 71645 -> 79839 bytes | |||
-rw-r--r-- | java/src/com/google/i18n/phonenumbers/AsYouTypeFormatter.java | 15 | ||||
-rw-r--r-- | java/src/com/google/i18n/phonenumbers/PhoneNumberUtil.java | 208 | ||||
-rw-r--r-- | java/src/com/google/i18n/phonenumbers/Phonenumber.java | 42 | ||||
-rw-r--r-- | java/src/com/google/i18n/phonenumbers/phonenumber.proto | 5 | ||||
-rw-r--r-- | java/test/com/google/i18n/phonenumbers/AsYouTypeFormatterTest.java | 53 | ||||
-rw-r--r-- | java/test/com/google/i18n/phonenumbers/PhoneNumberUtilTest.java | 35 |
9 files changed, 1082 insertions, 134 deletions
diff --git a/README.android b/README.android index 36dc582c..8939d6df 100644 --- a/README.android +++ b/README.android @@ -1,4 +1,4 @@ URL: http://code.google.com/p/libphonenumber/ -Version: r6 +Version: r9 License: Apache 2 Description: Google Phone Number Library. diff --git a/java/resources/com/google/i18n/phonenumbers/src/PhoneNumberMetaData.xml b/java/resources/com/google/i18n/phonenumbers/src/PhoneNumberMetaData.xml index b83058eb..0e72c87b 100644 --- a/java/resources/com/google/i18n/phonenumbers/src/PhoneNumberMetaData.xml +++ b/java/resources/com/google/i18n/phonenumbers/src/PhoneNumberMetaData.xml @@ -237,8 +237,60 @@ </territory> <!-- Albania --> + <!-- http://www.itu.int/oth/T0202000002/en --> <territory id="AL" countryCode="355" internationalPrefix="00" - nationalPrefix="0"> + nationalPrefix="0" nationalPrefixFormattingRule="$NP$FG"> + <availableFormats> + <!-- Formats mostly follow http://tirana.usembassy.gov/list_of_doctors.html --> + <numberFormat leadingDigits="4[0-6]" + pattern="(4)(\d{3})(\d{4})">$1 $2 $3</numberFormat> + <numberFormat leadingDigits="6" + pattern="(6[6-9])(\d{3})(\d{4})">$1 $2 $3</numberFormat> + <numberFormat leadingDigits="[2358][2-5]|4[7-9]" + pattern="(\d{2})(\d{3})(\d{3})">$1 $2 $3</numberFormat> + <numberFormat leadingDigits="[2358][16-9]" + pattern="(\d{3})(\d{5})">$1 $2</numberFormat> + <numberFormat leadingDigits="800" pattern="(800)(\d{4})">$1 $2</numberFormat> + <numberFormat leadingDigits="9|808" pattern="(\d{3})(\d{3})">$1 $2</numberFormat> + <numberFormat leadingDigits="7" pattern="(700)(\d{5})">$1 $2</numberFormat> + </availableFormats> + <generalDesc> + <nationalNumberPattern>[2-57]\d{7}|6\d{8}|8\d{5,7}|9\d{5}</nationalNumberPattern> + <possibleNumberPattern>\d{5,9}</possibleNumberPattern> + </generalDesc> + <fixedLine> + <nationalNumberPattern>(?:2(?:[168][1-9]|[247]\d|9[1-7])|3(?:1[1-3]|[2-6]\d|[79][1-8]|8[1-9])|4\d{2}|5(?:1[1-4]|[2-578]\d|6[1-5]|9[1-7])|8(?:[19][1-5]|[2-6]\d|[78][1-7]))\d{5}</nationalNumberPattern> + <possibleNumberPattern>\d{5,8}</possibleNumberPattern> + <exampleNumber>22345678</exampleNumber> + </fixedLine> + <mobile> + <nationalNumberPattern>6[6-9]\d{7}</nationalNumberPattern> + <possibleNumberPattern>\d{9}</possibleNumberPattern> + <exampleNumber>661234567</exampleNumber> + </mobile> + <tollFree> + <nationalNumberPattern>800\d{4}</nationalNumberPattern> + <possibleNumberPattern>\d{7}</possibleNumberPattern> + <exampleNumber>8001234</exampleNumber> + </tollFree> + <premiumRate> + <!-- It is named "Shared Revenue Services" in the plan, but as there is a separate "Shared + Cost Services", it is highly likely these numbers are premium rate numbers. No + information/example is found in the Internet. --> + <nationalNumberPattern>900\d{3}</nationalNumberPattern> + <possibleNumberPattern>\d{6}</possibleNumberPattern> + <exampleNumber>900123</exampleNumber> + </premiumRate> + <sharedCost> + <nationalNumberPattern>808\d{3}</nationalNumberPattern> + <possibleNumberPattern>\d{6}</possibleNumberPattern> + <exampleNumber>808123</exampleNumber> + </sharedCost> + <personalNumber> + <nationalNumberPattern>700\d{5}</nationalNumberPattern> + <possibleNumberPattern>\d{8}</possibleNumberPattern> + <exampleNumber>70012345</exampleNumber> + </personalNumber> </territory> <!-- Armenia --> @@ -251,8 +303,24 @@ </territory> <!-- Angola --> - <territory id="AO" countryCode="244" internationalPrefix="00" - nationalPrefix="0"> + <!-- http://www.itu.int/oth/T0202000006/en --> + <territory id="AO" countryCode="244" internationalPrefix="00"> + <availableFormats> + <numberFormat pattern="(\d{3})(\d{3})(\d{3})">$1 $2 $3</numberFormat> + </availableFormats> + <generalDesc> + <nationalNumberPattern>[29]\d{8}</nationalNumberPattern> + <possibleNumberPattern>\d{9}</possibleNumberPattern> + </generalDesc> + <fixedLine> + <nationalNumberPattern>2\d(?:[26-9]\d|\d[26-9])\d{5}</nationalNumberPattern> + <exampleNumber>222123456</exampleNumber> + </fixedLine> + <mobile> + <!-- Expanded the 92 prefix possibilities to matchnumbers found online. --> + <nationalNumberPattern>9[1-3]\d{7}</nationalNumberPattern> + <exampleNumber>923123456</exampleNumber> + </mobile> </territory> <!-- Argentina --> @@ -514,11 +582,11 @@ <possibleNumberPattern>\d{8,9}</possibleNumberPattern> </generalDesc> <fixedLine> - <nationalNumberPattern>(?:1(?:(?:2[3-5]|36|8\d|9)\d|02|1[0-589]|3[358]|4[013-79]|5[0-479]|6[0236-9]|7[0-24-8])|2(?:16|2\d|3[0-24]|4[1468]|55|6[56]|79))\d{5}</nationalNumberPattern> + <nationalNumberPattern>(?:1(?:(?:[28]\d|36|9)\d|02|1[0-589]|3[358]|4[013-79]|5[0-479]|6[0236-9]|7[0-24-8])|2(?:16|2\d|3[0-24]|4[1468]|55|6[56]|79))\d{5}</nationalNumberPattern> <exampleNumber>123123456</exampleNumber> </fixedLine> <mobile> - <nationalNumberPattern>(?:40|5[015]|7[07])\d{7}|60540\d{4}</nationalNumberPattern> + <nationalNumberPattern>(?:4[04]|5[015]|60|7[07])\d{7}</nationalNumberPattern> <possibleNumberPattern>\d{9}</possibleNumberPattern> <exampleNumber>401234567</exampleNumber> </mobile> @@ -617,7 +685,26 @@ </territory> <!-- Burkina Faso --> + <!-- http://www.itu.int/oth/T0202000021/en --> <territory id="BF" countryCode="226" internationalPrefix="00"> + <availableFormats> + <!-- The national numbering plan from ITU suggests grouping of 2, 2 and 4, but + we have chosen to use the standard from numbers found on the internet instead.--> + <numberFormat pattern="(\d{2})(\d{2})(\d{2})(\d{2})">$1 $2 $3 $4</numberFormat> + </availableFormats> + <generalDesc> + <nationalNumberPattern>[2457]\d{7}</nationalNumberPattern> + <possibleNumberPattern>\d{8}</possibleNumberPattern> + </generalDesc> + <fixedLine> + <!-- 50 48 and 50 49 exist as well. --> + <nationalNumberPattern>(?:20(?:49|5[23]|9[016-9])|40(?:4[569]|55|7[0179])|50[34]\d)\d{4}</nationalNumberPattern> + <exampleNumber>20491234</exampleNumber> + </fixedLine> + <mobile> + <nationalNumberPattern>7(?:[0168]\d|2[0-4]|4[01]|5[01346-9])\d{5}</nationalNumberPattern> + <exampleNumber>70123456</exampleNumber> + </mobile> </territory> <!-- Bulgaria --> @@ -665,11 +752,70 @@ </territory> <!-- Burundi --> + <!-- http://www.itu.int/oth/T0202000022/en --> <territory id="BI" countryCode="257" internationalPrefix="00"> + <availableFormats> + <numberFormat + pattern="([27]\d)(\d{2})(\d{2})(\d{2})">$1 $2 $3 $4</numberFormat> + </availableFormats> + <generalDesc> + <nationalNumberPattern>[27]\d{7}</nationalNumberPattern> + <possibleNumberPattern>\d{8}</possibleNumberPattern> + </generalDesc> + <fixedLine> + <nationalNumberPattern>22(?:2[0-7]|[3-5]0)\d{4}</nationalNumberPattern> + <exampleNumber>22201234</exampleNumber> + </fixedLine> + <mobile> + <!-- Extra online mobile number prefixes found: 79 10, 78 \d{2} and + 76 [29]\d. --> + <!-- The 2955 prefix is listed as a mobile prefix, but many people list + it as their fixed home number. We will keep it as mobile for now, but it + may actually be a prefix for fixed satellite phones. --> + <nationalNumberPattern>(?:2955|7(?:9(?:5[6-9]|[19]\d)|(?:6[269]|77|8\d)\d))\d{4}</nationalNumberPattern> + <exampleNumber>79561234</exampleNumber> + </mobile> </territory> <!-- Benin --> + <!-- http://www.itu.int/oth/T0202000017/en --> <territory id="BJ" countryCode="229" internationalPrefix="00"> + <availableFormats> + <numberFormat pattern="(\d{2})(\d{2})(\d{2})(\d{2})">$1 $2 $3 $4</numberFormat> + <!-- Numbers beginning with 7 should be formatted as a block. --> + </availableFormats> + <generalDesc> + <nationalNumberPattern>[289]\d{7}|7\d{3}</nationalNumberPattern> + <possibleNumberPattern>\d{4,8}</possibleNumberPattern> + </generalDesc> + <fixedLine> + <!-- These come from the national numbering plan, but have been widened + to include other prefixes found in the yellow pages - specifically 21 + 0.--> + <nationalNumberPattern>2(?:02|1[037]|2[45]|3[68])\d{5}</nationalNumberPattern> + <possibleNumberPattern>\d{8}</possibleNumberPattern> + <exampleNumber>20211234</exampleNumber> + </fixedLine> + <mobile> + <!-- 93 0, 93 4, 93 5 and 93 8 have been added as many online examples + of these prefixes can be found. --> + <nationalNumberPattern>9(?:0[069]|[35][0-2457-9]|7[014-9])\d{5}</nationalNumberPattern> + <possibleNumberPattern>\d{8}</possibleNumberPattern> + <exampleNumber>90011234</exampleNumber> + </mobile> + <tollFree> + <nationalNumberPattern>7[3-5]\d{2}</nationalNumberPattern> + <possibleNumberPattern>\d{4}</possibleNumberPattern> + <exampleNumber>7312</exampleNumber> + </tollFree> + <!-- Other numbers beginning with 81 are reserved for _either_ free phone + or shared-cost, but there is no clear differentiation between these. These + need to be modelled in some other way. --> + <voip> + <nationalNumberPattern>857[58]\d{4}</nationalNumberPattern> + <possibleNumberPattern>\d{8}</possibleNumberPattern> + <exampleNumber>85751234</exampleNumber> + </voip> </territory> <!-- French Dept. of Guadeloupe --> @@ -685,11 +831,11 @@ <possibleNumberPattern>\d{7,10}</possibleNumberPattern> </generalDesc> <fixedLine> - <nationalNumberPattern>441(?:2(?:02|23|[3479]\d)|[46]\d{2}|5(?:40|89)|824)\d{4}</nationalNumberPattern> + <nationalNumberPattern>441(?:2(?:02|23|61|[3479]\d)|[46]\d{2}|5(?:4\d|60|89)|824)\d{4}</nationalNumberPattern> <exampleNumber>4412345678</exampleNumber> </fixedLine> <mobile> - <nationalNumberPattern>441(?:[37]\d{2}|5(?:[0-3]\d|9[09]))\d{4}</nationalNumberPattern> + <nationalNumberPattern>441(?:[37]\d|5[0-39])\d{5}</nationalNumberPattern> <possibleNumberPattern>\d{10}</possibleNumberPattern> <exampleNumber>4413701234</exampleNumber> </mobile> @@ -906,11 +1052,50 @@ </territory> <!-- Central African Republic --> + <!-- http://www.itu.int/oth/T0202000028/en --> <territory id="CF" countryCode="236" internationalPrefix="00"> + <availableFormats> + <numberFormat pattern="(\d{2})(\d{2})(\d{2})(\d{2})">$1 $2 $3 $4</numberFormat> + </availableFormats> + <generalDesc> + <nationalNumberPattern>[278]\d{7}</nationalNumberPattern> + <possibleNumberPattern>\d{8}</possibleNumberPattern> + </generalDesc> + <fixedLine> + <nationalNumberPattern>2[12]\d{6}</nationalNumberPattern> + <exampleNumber>21612345</exampleNumber> + </fixedLine> + <mobile> + <nationalNumberPattern>7[0257]\d{6}</nationalNumberPattern> + <exampleNumber>70012345</exampleNumber> + </mobile> + <premiumRate> + <nationalNumberPattern>8776\d{4}</nationalNumberPattern> + <exampleNumber>87761234</exampleNumber> + </premiumRate> </territory> <!-- Congo (Rep. of the) (Brazzaville) --> + <!-- http://www.itu.int/oth/T020200002E/en --> <territory id="CG" countryCode="242" internationalPrefix="00"> + <availableFormats> + <numberFormat pattern="(\d{3})(\d{4})">$1 $2</numberFormat> + </availableFormats> + <generalDesc> + <nationalNumberPattern>[24-68]\d{6}</nationalNumberPattern> + <possibleNumberPattern>\d{7}</possibleNumberPattern> + </generalDesc> + <fixedLine> + <!-- Revision to plan in December 2009 says that the prefix '8' + is to be used temporarily for fixed-line numbers while + awaiting revision of the plan. --> + <nationalNumberPattern>(?:2[1-589]|8\d)\d{5}</nationalNumberPattern> + <exampleNumber>2123456</exampleNumber> + </fixedLine> + <mobile> + <nationalNumberPattern>[4-6]\d{6}</nationalNumberPattern> + <exampleNumber>5012345</exampleNumber> + </mobile> </territory> <!-- Switzerland --> @@ -1158,11 +1343,58 @@ </territory> <!-- Cape Verde --> + <!-- http://www.itu.int/oth/T0202000026/en --> <territory id="CV" countryCode="238" internationalPrefix="0"> + <availableFormats> + <numberFormat pattern="(\d{3})(\d{2})(\d{2})">$1 $2 $3</numberFormat> + </availableFormats> + <generalDesc> + <nationalNumberPattern>[29]\d{6}</nationalNumberPattern> + <possibleNumberPattern>\d{7}</possibleNumberPattern> + </generalDesc> + <fixedLine> + <nationalNumberPattern>2(?:2[1-7]|3[0-8]|4[12]|5[1256]|6\d|7[1-3]|8[1-5])\d{4}</nationalNumberPattern> + <exampleNumber>2211234</exampleNumber> + </fixedLine> + <mobile> + <nationalNumberPattern>9[189]\d{5}</nationalNumberPattern> + <exampleNumber>9911234</exampleNumber> + </mobile> </territory> <!-- Cyprus --> + <!-- http://www.itu.int/oth/T0202000034/en --> <territory id="CY" countryCode="357" internationalPrefix="00"> + <availableFormats> + <!-- Format from http://www.cyprusyellowpages.com/--> + <numberFormat pattern="([27-9]\d)(\d{6})">$1 $2</numberFormat> + </availableFormats> + <generalDesc> + <nationalNumberPattern>[27-9]\d{7}</nationalNumberPattern> + <possibleNumberPattern>\d{8}</possibleNumberPattern> + </generalDesc> + <fixedLine> + <nationalNumberPattern>2[2-6]\d{6}</nationalNumberPattern> + <exampleNumber>22345678</exampleNumber> + </fixedLine> + <mobile> + <!-- Universal Access Service numbers (7777 xxxx) are included here, as they are + classified as Mobile in the Cyprus national numbering plan. --> + <nationalNumberPattern>7777\d{4}|9(?:[69]\d|7[67])\d{5}</nationalNumberPattern> + <exampleNumber>96123456</exampleNumber> + </mobile> + <tollFree> + <nationalNumberPattern>8000\d{4}</nationalNumberPattern> + <exampleNumber>80001234</exampleNumber> + </tollFree> + <premiumRate> + <nationalNumberPattern>9009\d{4}</nationalNumberPattern> + <exampleNumber>90091234</exampleNumber> + </premiumRate> + <personalNumber> + <nationalNumberPattern>700\d{5}</nationalNumberPattern> + <exampleNumber>70012345</exampleNumber> + </personalNumber> </territory> <!-- Czech Rep. --> @@ -1273,7 +1505,30 @@ </territory> <!-- Djibouti --> + <!-- http://www.itu.int/oth/T020200003A/en --> <territory id="DJ" countryCode="253" internationalPrefix="00"> + <availableFormats> + <!-- The number format here is suggested in the plan and used online, + although the phone numbers of the national numbering authority itself on + the plan do not follow this. --> + <numberFormat pattern="([2-8]\d)(\d{2})(\d{2})">$1 $2 $3</numberFormat> + </availableFormats> + <generalDesc> + <nationalNumberPattern>[2-8]\d{5}</nationalNumberPattern> + <possibleNumberPattern>\d{6}</possibleNumberPattern> + </generalDesc> + <fixedLine> + <!-- 32 and 33 are not mentioned in the plan, but seem to be in use. 32 + is the prefix of the phone number for the Télécom company itself. --> + <nationalNumberPattern>(?:25|3[0-6]|42)\d{4}</nationalNumberPattern> + <exampleNumber>251234</exampleNumber> + </fixedLine> + <mobile> + <!-- 86 and 87 have been added as prefixes since them seem to be widely + used in numbers found online. --> + <nationalNumberPattern>(?:[5-7]\d|8[0-7])\d{4}</nationalNumberPattern> + <exampleNumber>601234</exampleNumber> + </mobile> </territory> <!-- Denmark --> @@ -1454,8 +1709,27 @@ </territory> <!-- Eritrea --> + <!-- http://www.itu.int/oth/T0202000042/en --> <territory id="ER" countryCode="291" internationalPrefix="00" - nationalPrefix="0"> + nationalPrefix="0" nationalPrefixFormattingRule="$NP$FG"> + <availableFormats> + <numberFormat pattern="(\d)(\d{3})(\d{3})">$1 $2 $3</numberFormat> + </availableFormats> + <generalDesc> + <nationalNumberPattern>[178]\d{6}</nationalNumberPattern> + <possibleNumberPattern>\d{6,7}</possibleNumberPattern> + </generalDesc> + <fixedLine> + <nationalNumberPattern>1(?:1[12568]|20|40|55|6[146])\d{4}|8\d{6}</nationalNumberPattern> + <exampleNumber>8370362</exampleNumber><!-- Test number from plan.--> + </fixedLine> + <mobile> + <!-- It is unclear in the plan whether the 07 mobile prefix superseded the previous + 017[1-3] numbers or was in addition to them, so we support both here.--> + <nationalNumberPattern>17[1-3]\d{4}|7\d{6}</nationalNumberPattern> + <possibleNumberPattern>\d{7}</possibleNumberPattern> + <exampleNumber>7123456</exampleNumber> + </mobile> </territory> <!-- Spain --> @@ -1495,8 +1769,27 @@ </territory> <!-- Ethiopia --> + <!-- http://www.itu.int/oth/T0202000044/en --> <territory id="ET" countryCode="251" internationalPrefix="00" - nationalPrefix="0"> + nationalPrefix="0" nationalPrefixFormattingRule="$NP$FG"> + <availableFormats> + <numberFormat pattern="([1-59]\d)(\d{3})(\d{4})">$1 $2 $3</numberFormat> + </availableFormats> + <generalDesc> + <nationalNumberPattern>[1-59]\d{8}</nationalNumberPattern> + <possibleNumberPattern>\d{7,9}</possibleNumberPattern> + </generalDesc> + <fixedLine> + <nationalNumberPattern>(?:11(?:1(?:1[124]|2[2-57]|3[1-5]|5[5-8]|8[6-8])|2(?:13|3[6-8]|5[89]|7[05-9]|8[2-6])|3(?:2[01]|3[0-289]|4[1289]|7[1-4]|87)|4(?:1[69]|3[2-49]|4[0-23]|6[5-8])|5(?:1[57]|44|5[0-4])|6(?:18|2[69]|4[5-7]|5[1-5]|6[0-59]|8[015-8]))|2(?:2(?:11[1-9]|22[0-7]|33\d|44[1467]|66[1-68])|5(?:11[124-6]|33[2-8]|44[1467]|55[14]|66[1-3679]|77[124-79]|880))|3(?:3(?:11[0-46-8]|22[0-6]|33[0134689]|44[04]|55[0-6]|66[01467])|4(?:44[0-8]|55[0-69]|66[0-3]|77[1-5]))|4(?:6(?:22[0-24-7]|33[1-5]|44[13-69]|55[14-689]|660|88[1-4])|7(?:11[1-9]|22[1-9]|33[13-7]|44[13-6]|55[1-689]))|5(?:7(?:227|55[05]|(?:66|77)[14-8])|8(?:11[149]|22[013-79]|33[0-68]|44[013-8]|550|66[1-5]|77\d)))\d{4}</nationalNumberPattern> + <exampleNumber>111112345</exampleNumber> + </fixedLine> + <mobile> + <!-- Some additional area codes are permitted here in line with online + numbers, namely 91 13[4-6], 91 17[2-6], 91 31\d, 91 43[2489]. --> + <nationalNumberPattern>91(?:1(?:[146]\d|2[0-5]|3[4-6]|50|7[2-6]|8[46-9])|31\d|4(?:3[0-2489]|7[0-3])|5(?:3[23]|7[3-5])|6(?:58|8[23])|7(?:5[57]|8[01])|8(?:3[45]|7[67]))\d{4}</nationalNumberPattern> + <possibleNumberPattern>\d{9}</possibleNumberPattern> + <exampleNumber>911123456</exampleNumber> + </mobile> </territory> <!-- Finland --> @@ -1593,7 +1886,35 @@ </territory> <!-- Gabon --> + <!-- http://www.itu.int/oth/T020200004E/en --> <territory id="GA" countryCode="241" internationalPrefix="00"> + <availableFormats> + <numberFormat leadingDigits="[4-9]" pattern="(\d{2})(\d{2})(\d{2})">$1 $2 $3</numberFormat> + <numberFormat leadingDigits="0" pattern="(0\d)(\d{2})(\d{2})(\d{2})">$1 $2 $3 $4</numberFormat> + </availableFormats> + <generalDesc> + <nationalNumberPattern>[4-9]\d{5}|0\d{7}</nationalNumberPattern> + <possibleNumberPattern>\d{6,8}</possibleNumberPattern> + </generalDesc> + <fixedLine> + <nationalNumberPattern>(?:4(?:[04-8]\d|2[04])|(?:5[04-689]|6[024-9]|7\d|8[236]|9[02368])\d)\d{3}</nationalNumberPattern> + <possibleNumberPattern>\d{6}</possibleNumberPattern> + <exampleNumber>441234</exampleNumber> + </fixedLine> + <!-- The leading zero here is supposed to be temporary - at a later date, + Gabon intends to have a 0 as their national prefix for all numbers + instead. --> + <!-- http://www.wtng.info/wtng-241-ga.html was used as the basis for the + acceptable prefixes, with some supplementary prefixes added from internet + research. There is supposedly a resource on mobile prefixes on the Gabon + Telecom website, but the site (www.ogooue.ga) doesn't seem to work and no + alternative can be found. Extra prefixes added: 07 12, 07 13, 06 71, 07 + 33, 07 [67]\d --> + <mobile> + <nationalNumberPattern>0(?:5(?:0[89]|3[0-4]|8[0-26]|9[238])|6(?:0[3-7]|1[01]|2[0-7]|6[0-589]|71|83|9[57])|7(?:1[2-5]|2[89]|3[35-9]|4[01]|5[0-347-9]|[67]\d|8[457-9]|9[0146]))\d{4}</nationalNumberPattern> + <possibleNumberPattern>\d{8}</possibleNumberPattern> + <exampleNumber>06031234</exampleNumber> + </mobile> </territory> <!-- United Kingdom --> @@ -1750,6 +2071,7 @@ <!-- Ghana --> <!-- http://www.itu.int/dms_pub/itu-t/oth/02/02/T02020000520001MSWE.doc --> + <!-- http://www.nca.org.gh/index.php?option=com_content&view=article&id=90&Itemid=65 --> <territory id="GH" countryCode="233" internationalPrefix="00" nationalPrefix="0" nationalPrefixFormattingRule="$NP$FG"> <availableFormats> @@ -1758,7 +2080,7 @@ <numberFormat leadingDigits="25|31|[4-9]" pattern="([2-9]\d{2})(\d{3,5})">$1 $2</numberFormat> <numberFormat leadingDigits="3[02-9]" pattern="(3\d)(\d{3})(\d{4})">$1 $2 $3</numberFormat> - <numberFormat leadingDigits="2[47]" pattern="(2[47])(\d{3})(\d{3})">$1 $2 $3</numberFormat> + <numberFormat leadingDigits="2[47]" pattern="(2[47])(\d{3})(\d{3,4})">$1 $2 $3</numberFormat> <numberFormat leadingDigits="2[0368]|54" pattern="([25]\d)(\d{3})(\d{4})">$1 $2 $3</numberFormat> </availableFormats> @@ -1774,7 +2096,7 @@ <exampleNumber>251234</exampleNumber> </fixedLine> <mobile> - <nationalNumberPattern>2(?:755\d{4}|(?:4|08)\d{6}|[368]\d{7})|54\d{7}</nationalNumberPattern> + <nationalNumberPattern>2(?:755\d{4}|(?:4\d?|08)\d{6}|[368]\d{7})|54\d{7}</nationalNumberPattern> <possibleNumberPattern>\d{8,9}</possibleNumberPattern> <exampleNumber>27551234</exampleNumber> </mobile> @@ -1790,7 +2112,23 @@ </territory> <!-- Gambia --> + <!-- http://www.itu.int/oth/T020200004F/en --> <territory id="GM" countryCode="220" internationalPrefix="00"> + <availableFormats> + <numberFormat pattern="(\d{3})(\d{4})">$1 $2</numberFormat> + </availableFormats> + <generalDesc> + <nationalNumberPattern>[3-9]\d{6}</nationalNumberPattern> + <possibleNumberPattern>\d{7}</possibleNumberPattern> + </generalDesc> + <fixedLine> + <nationalNumberPattern>(4(?:[23]\d{2}|4(?:1[024679]|[6-9]\d))|5(?:54[0-7]|6(?:[67]\d)|7(?:1[04]|2[035]|3[58]|48))|8\d{3})\d{3}</nationalNumberPattern> + <exampleNumber>5661234</exampleNumber> + </fixedLine> + <mobile> + <nationalNumberPattern>[3679]\d{6}</nationalNumberPattern> + <exampleNumber>3012345</exampleNumber> + </mobile> </territory> <!-- Guinea --> @@ -1803,7 +2141,25 @@ </territory> <!-- Equatorial Guinea --> + <!-- http://www.itu.int/oth/T0202000041/en --> <territory id="GQ" countryCode="240" internationalPrefix="00"> + <availableFormats> + <!-- Follows yellow page format from + http://malabophonebook.com/en/area/bata/ --> + <numberFormat pattern="(\d{2})(\d{2})(\d{2})">$1 $2 $3</numberFormat> + </availableFormats> + <generalDesc> + <nationalNumberPattern>[0256]\d{5}</nationalNumberPattern> + <possibleNumberPattern>\d{6}</possibleNumberPattern> + </generalDesc> + <fixedLine> + <nationalNumberPattern>0[46-9]\d{4}</nationalNumberPattern> + <exampleNumber>041234</exampleNumber> + </fixedLine> + <mobile> + <nationalNumberPattern>[256]\d{5}</nationalNumberPattern> + <exampleNumber>212345</exampleNumber> + </mobile> </territory> <!-- Greece --> @@ -1884,7 +2240,23 @@ </territory> <!-- Guinea-Bissau --> + <!-- http://www.itu.int/oth/T020200005C/en --> <territory id="GW" countryCode="245" internationalPrefix="00"> + <availableFormats> + <numberFormat pattern="(\d{3})(\d{4})">$1 $2</numberFormat> + </availableFormats> + <generalDesc> + <nationalNumberPattern>[3567]\d{6}</nationalNumberPattern> + <possibleNumberPattern>\d{7}</possibleNumberPattern> + </generalDesc> + <fixedLine> + <nationalNumberPattern>3(?:2[0125]|3[1245]|4[12]|5[1-4]|70|9[1-467])\d{4}</nationalNumberPattern> + <exampleNumber>3201234</exampleNumber> + </fixedLine> + <mobile> + <nationalNumberPattern>[5-7]\d{6}</nationalNumberPattern> + <exampleNumber>5012345</exampleNumber> + </mobile> </territory> <!-- Guyana --> @@ -2086,12 +2458,13 @@ </territory> <!-- Ireland --> + <!-- http://www.comreg.ie/_fileupload/publications/ComReg0802.pdf --> <!-- http://www.comreg.ie/_fileupload/publications/ComReg0435.pdf --> <!-- http://www.comreg.ie/_fileupload/publications/ComReg03147.pdf --> <territory id="IE" countryCode="353" internationalPrefix="00" nationalPrefix="0" nationalPrefixFormattingRule="($NP$FG)"> <availableFormats> - <numberFormat leadingDigits="1" pattern="(1)(\d{3})(\d{4})">$1 $2 $3</numberFormat> + <numberFormat leadingDigits="1" pattern="(1)(\d{3,4})(\d{4})">$1 $2 $3</numberFormat> <numberFormat leadingDigits="2[2-9]|4[347]|5[2-58]|6[2-47-9]|9[3-9]" pattern="(\d{2})(\d{5})">$1 $2</numberFormat> <numberFormat leadingDigits="40[24]|50[45]" pattern="(\d{3})(\d{5})">$1 $2</numberFormat> @@ -2126,7 +2499,7 @@ people dial, allowing them to easily dial Northern Ireland. We support these numbers here, although technically they are numbers for the UK. --> - <nationalNumberPattern>(?:2[24-9]|4(?:0[24]|7)|5(?:0[45]|8)|6[237-9]|9[3-9])\d{5}|(?:45|[569]1|818)\d{6}|(?:1|4[12469]|5[3679]|6[56]|7[14]|9[04])\d{7}|21\d{6,7}|(?:23|4[34]|52|64)\d{5,7}|48\d{8}</nationalNumberPattern> + <nationalNumberPattern>1\d{7,8}|(?:2[24-9]|4(?:0[24]|7)|5(?:0[45]|8)|6[237-9]|9[3-9])\d{5}|(?:45|[569]1|818)\d{6}|(?:4[12469]|5[3679]|6[56]|7[14]|9[04])\d{7}|21\d{6,7}|(?:23|4[34]|52|64)\d{5,7}|48\d{8}</nationalNumberPattern> <possibleNumberPattern>\d{5,10}</possibleNumberPattern> <exampleNumber>2212345</exampleNumber> </fixedLine> @@ -2141,7 +2514,7 @@ <exampleNumber>1800123456</exampleNumber> </tollFree> <premiumRate> - <nationalNumberPattern>15(?:1[2-9]|[2-9]0|59)\d{6}</nationalNumberPattern> + <nationalNumberPattern>15(?:1[2-9]|[2-8]0|59|9[089])\d{6}</nationalNumberPattern> <possibleNumberPattern>\d{10}</possibleNumberPattern> <exampleNumber>1520123456</exampleNumber> </premiumRate> @@ -2690,7 +3063,25 @@ </territory> <!-- Comoros --> + <!-- http://www.itu.int/oth/T020200002D/en --> <territory id="KM" countryCode="269" internationalPrefix="00"> + <availableFormats> + <numberFormat pattern="(\d)(\d{3})(\d{3})">$1 $2 $3</numberFormat> + </availableFormats> + <generalDesc> + <nationalNumberPattern>[37]\d{6}</nationalNumberPattern> + <possibleNumberPattern>\d{7}</possibleNumberPattern> + </generalDesc> + <fixedLine> + <!-- CDMA phones are included here, as they are considered as an extension of fixed line: + http://www.comorestelecom.km/presentationcdma.php --> + <nationalNumberPattern>7(?:6[0-37-9]|7[0-57-9])\d{4}</nationalNumberPattern> + <exampleNumber>7712345</exampleNumber> + </fixedLine> + <mobile> + <nationalNumberPattern>3[23]\d{5}</nationalNumberPattern> + <exampleNumber>3212345</exampleNumber> + </mobile> </territory> <!-- Saint Kitts and Nevis --> @@ -2987,8 +3378,32 @@ </territory> <!-- Liberia --> + <!-- http://www.itu.int/oth/T0202000079/en --> <territory id="LR" countryCode="231" internationalPrefix="00" - nationalPrefix="22"> + nationalPrefix="0" nationalPrefixFormattingRule="$NP$FG"> + <availableFormats> + <!-- Formatting from Ministry of Agriculture, + http://www.moa.gov.lr/content.php?sub=Email&?related=Contacts --> + <numberFormat leadingDigits="[27]" + pattern="([27]\d)(\d{3})(\d{3})">$1 $2 $3</numberFormat> + <numberFormat leadingDigits="[4-6]" + pattern="([4-6])(\d{3})(\d{3})">$1 $2 $3</numberFormat> + </availableFormats> + <generalDesc> + <nationalNumberPattern>(?:[27]\d|[4-6])\d{6}</nationalNumberPattern> + <possibleNumberPattern>\d{7,8}</possibleNumberPattern> + </generalDesc> + <fixedLine> + <nationalNumberPattern>2\d{7}</nationalNumberPattern> + <possibleNumberPattern>\d{8}</possibleNumberPattern> + <exampleNumber>21234567</exampleNumber> + </fixedLine> + <mobile> + <!-- Added 66, 67 and 68 as prefixes because of online numbers + fitting this pattern. --> + <nationalNumberPattern>(?:4[67]|5\d|7\d{2}|6[4-8])\d{5}</nationalNumberPattern> + <exampleNumber>4612345</exampleNumber> + </mobile> </territory> <!-- Lesotho --> @@ -3079,8 +3494,36 @@ </territory> <!-- Moldova, Rep. of --> + <!-- http://www.itu.int/oth/T020200008C/en --> <territory id="MD" countryCode="373" internationalPrefix="00" - nationalPrefix="0"> + nationalPrefix="0" nationalPrefixFormattingRule="$NP$FG"> + <availableFormats> + <numberFormat leadingDigits="22" pattern="(22)(\d{3})(\d{3})">$1 $2 $3</numberFormat> + <numberFormat leadingDigits="2[13-79]|[5-7]" + pattern="([25-7]\d{2})(\d{2})(\d{3})">$1 $2 $3</numberFormat> + <numberFormat leadingDigits="[89]" pattern="([89]00)(\d{5})">$1 $2</numberFormat> + </availableFormats> + <generalDesc> + <nationalNumberPattern>[256-9]\d{7}</nationalNumberPattern> + <possibleNumberPattern>\d{8}</possibleNumberPattern> + </generalDesc> + <fixedLine> + <nationalNumberPattern>(?:2(?:1[0569]|2\d|3[015-7]|4[1-46-9]|5[0-24689]|6[2-589]|7[1-37]|9[1347-9])|5(?:33|5[257]))\d{5}</nationalNumberPattern> + <possibleNumberPattern>\d{5,8}</possibleNumberPattern> + <exampleNumber>22212345</exampleNumber> + </fixedLine> + <mobile> + <nationalNumberPattern>(?:6(?:50|7[12]|8[0-7]|9\d)|7(?:80|9\d))\d{5}</nationalNumberPattern> + <exampleNumber>65012345</exampleNumber> + </mobile> + <tollFree> + <nationalNumberPattern>800\d{5}</nationalNumberPattern> + <exampleNumber>80012345</exampleNumber> + </tollFree> + <premiumRate> + <nationalNumberPattern>900\d{5}</nationalNumberPattern> + <exampleNumber>90012345</exampleNumber> + </premiumRate> </territory> <!-- Montenegro --> @@ -3089,8 +3532,31 @@ </territory> <!-- Madagascar --> + <!-- http://www.itu.int/oth/T020200007F/en --> <territory id="MG" countryCode="261" internationalPrefix="00" - nationalPrefix="0"> + nationalPrefix="0" nationalPrefixFormattingRule="$NP$FG"> + <availableFormats> + <numberFormat pattern="([23]\d)(\d{2})(\d{3})(\d{2})">$1 $2 $3 $4</numberFormat> + </availableFormats> + <generalDesc> + <nationalNumberPattern>[23]\d{8}</nationalNumberPattern> + <possibleNumberPattern>\d{7,9}</possibleNumberPattern> + </generalDesc> + <fixedLine> + <!-- Added the prefixes 20 44 and 20 47 as they seem popular on the + internet - the plan says 20 4 is for the rest of the province of + Antanarivo, but then fails to mention any area codes beginning with 4. + --> + <nationalNumberPattern>2(?:0(?:(?:2\d|4[47]|5[3467]|6[279]|8[268]|9[245])\d|7(?:2[29]|[35]\d))|210\d)\d{4}</nationalNumberPattern> + <exampleNumber>202123456</exampleNumber> + </fixedLine> + <mobile> + <!-- The numbering plan suggests the third digit, Z, should be 24-9, + but this is not borne out by reality.--> + <nationalNumberPattern>3[02-4]\d{7}</nationalNumberPattern> + <possibleNumberPattern>\d{9}</possibleNumberPattern> + <exampleNumber>301234567</exampleNumber> + </mobile> </territory> <!-- Marshall Islands --> @@ -3099,13 +3565,73 @@ </territory> <!-- Macedonia, Former Yugoslav Rep. of --> + <!-- http://en.wikipedia.org/wiki/%2B389 + http://www.aek.mk/ go to Telecommunications, Numbering, then Numbering plan. --> <territory id="MK" countryCode="389" internationalPrefix="00" - nationalPrefix="0"> + nationalPrefix="0" nationalPrefixFormattingRule="$NP$FG"> + <availableFormats> + <!-- Formats follow wikipedia. --> + <numberFormat leadingDigits="2" pattern="(2)(\d{3})(\d{4})">$1 $2 $3</numberFormat> + <numberFormat leadingDigits="[347]" + pattern="([347]\d)(\d{3})(\d{3})">$1 $2 $3</numberFormat> + <numberFormat leadingDigits="[58]" + pattern="([58]\d{2})(\d)(\d{2})(\d{2})">$1 $2 $3 $4</numberFormat> + </availableFormats> + <generalDesc> + <nationalNumberPattern>[2-578]\d{7}</nationalNumberPattern> + <possibleNumberPattern>\d{8}</possibleNumberPattern> + </generalDesc> + <fixedLine> + <nationalNumberPattern>(?:2\d|3[1-4]|4[2-8])\d{6}</nationalNumberPattern> + <possibleNumberPattern>\d{6,8}</possibleNumberPattern> + <exampleNumber>22212345</exampleNumber> + </fixedLine> + <mobile> + <nationalNumberPattern>7\d{7}</nationalNumberPattern> + <exampleNumber>72345678</exampleNumber> + </mobile> + <tollFree> + <nationalNumberPattern>800\d{5}</nationalNumberPattern> + <exampleNumber>80012345</exampleNumber> + </tollFree> + <premiumRate> + <nationalNumberPattern>5[02-9]\d{6}</nationalNumberPattern> + <exampleNumber>50012345</exampleNumber> + </premiumRate> + <sharedCost> + <nationalNumberPattern>8(?:0[1-9]|[1-9]\d)\d{5}</nationalNumberPattern> + <exampleNumber>80123456</exampleNumber> + </sharedCost> </territory> <!-- Mali --> + <!-- http://www.itu.int/oth/T0202000083/en --> + <!-- http://crt-mali.org/pdf/plan_num --> <territory id="ML" countryCode="223" internationalPrefix="00" nationalPrefix="0"> + <availableFormats> + <numberFormat pattern="([246-8]\d)(\d{2})(\d{2})(\d{2})">$1 $2 $3 $4</numberFormat> + </availableFormats> + <generalDesc> + <nationalNumberPattern>[246-8]\d{7}</nationalNumberPattern> + <possibleNumberPattern>\d{8}</possibleNumberPattern> + </generalDesc> + <fixedLine> + <!-- 20 70 seems a common pattern, in addition to 20 79. 21 25 seems + also to exist. --> + <nationalNumberPattern>(?:2(?:0(?:2[0-589]|7[027-9])|1(?:2[5-7]|[3-9]\d))|442\d)\d{4}</nationalNumberPattern> + <exampleNumber>20212345</exampleNumber> + </fixedLine> + <mobile> + <nationalNumberPattern>(?:6(?:[569]\d)|7(?:[359][0-4]|4[014-7]|6\d|8[1-9]))\d{5}</nationalNumberPattern> + <exampleNumber>65012345</exampleNumber> + </mobile> + <tollFree> + <!-- Online examples have not been found, but this seems to follow the + prescriptions in the plan. --> + <nationalNumberPattern>800\d{5}</nationalNumberPattern> + <exampleNumber>80012345</exampleNumber> + </tollFree> </territory> <!-- Myanmar --> @@ -3230,8 +3756,24 @@ </territory> <!-- Mauritania --> - <territory id="MR" countryCode="222" internationalPrefix="00" - nationalPrefix="0"> + <!-- http://www.itu.int/oth/T0202000087/en --> + <!-- http://www.are.mr/com-1-4-1.html --> + <territory id="MR" countryCode="222" internationalPrefix="00" > + <availableFormats> + <numberFormat pattern="([2-7]\d{2})(\d{2})(\d{2})">$1 $2 $3</numberFormat> + </availableFormats> + <generalDesc> + <nationalNumberPattern>[2-7]\d{6}</nationalNumberPattern> + <possibleNumberPattern>\d{7}</possibleNumberPattern> + </generalDesc> + <fixedLine> + <nationalNumberPattern>5(?:1[035]|2[0-69]|3[0348]|4[468]|5[02-467]|6[39]|7[4-69])\d{4}</nationalNumberPattern> + <exampleNumber>5131234</exampleNumber> + </fixedLine> + <mobile> + <nationalNumberPattern>(?:[23][0-4]|4[3-5]|6\d|7[0-7])\d{5}</nationalNumberPattern> + <exampleNumber>3123456</exampleNumber> + </mobile> </territory> <!-- Montserrat --> @@ -3286,12 +3828,15 @@ <!-- Wireless local loop numbers are considered to be fixed, since there is almost no roaming capability. --> <nationalNumberPattern>(?:2(?:[034789]\d|1[0-8]|2[0-79])|4(?:[013-8]\d|2[4-7])|[56]\d{2}|8(?:14|3[129]))\d{4}</nationalNumberPattern> + <exampleNumber>2012345</exampleNumber> </fixedLine> <mobile> <nationalNumberPattern>(?:25\d|4(?:2[12389]|9\d)|7\d{2}|87[15-7]|9[13-8]\d)\d{4}</nationalNumberPattern> + <exampleNumber>2512345</exampleNumber> </mobile> <tollFree> <nationalNumberPattern>80[012]\d{4}</nationalNumberPattern> + <exampleNumber>8001234</exampleNumber> </tollFree> <!-- These may be either shared cost or premium rate - they don't differentiate between these in the plan. This is expected to change with @@ -3299,6 +3844,7 @@ this will be updated appropriately. --> <premiumRate> <nationalNumberPattern>30\d{5}</nationalNumberPattern> + <exampleNumber>3012345</exampleNumber> </premiumRate> </territory> @@ -3308,7 +3854,37 @@ </territory> <!-- Malawi --> - <territory id="MW" countryCode="265" internationalPrefix="00"> + <!-- http://www.itu.int/oth/T0202000080/en --> + <!-- The plan doesn't state that a national prefix exists, but + numbers found on the internet are consistent in having one.--> + <territory id="MW" countryCode="265" internationalPrefix="00" + nationalPrefix="0" nationalPrefixFormattingRule="$NP$FG"> + <availableFormats> + <numberFormat leadingDigits="[13-5]" + pattern="(\d)(\d{3})(\d{3})">$1 $2 $3</numberFormat> + <numberFormat leadingDigits="2" + pattern="(2\d{2})(\d{3})(\d{3})">$1 $2 $3</numberFormat> + <numberFormat leadingDigits="7" + pattern="(\d)(\d{4})(\d{4})">$1 $2 $3</numberFormat> + <numberFormat leadingDigits="[89]" + pattern="(\d)(\d{3,4})(\d{3,4})">$1 $2 $3</numberFormat> + </availableFormats> + <!-- According to the plan, the switch from 7 to 9 digits for mobile + numbers happened in July 2009. However, online numbers don't + seem to reflect this - even on the telephone company websites such as + www.mw.zain.com. Allowing both for now. --> + <generalDesc> + <nationalNumberPattern>(?:[13-5]|[27]\d{2}|[89](?:\d{2})?)\d{6}</nationalNumberPattern> + <possibleNumberPattern>\d{7,9}</possibleNumberPattern> + </generalDesc> + <fixedLine> + <nationalNumberPattern>(?:1[2-9]|21\d{2})\d{5}</nationalNumberPattern> + <exampleNumber>1234567</exampleNumber> + </fixedLine> + <mobile> + <nationalNumberPattern>(?:[3-5]|77|8(?:8\d)?|9(?:9\d)?)\d{6}</nationalNumberPattern> + <exampleNumber>991234567</exampleNumber> + </mobile> </territory> <!-- Mexico --> @@ -3433,13 +4009,81 @@ </territory> <!-- Mozambique --> - <territory id="MZ" countryCode="258" internationalPrefix="00" - nationalPrefix="0"> + <!-- http://www.itu.int/oth/T0202000091/en --> + <territory id="MZ" countryCode="258" internationalPrefix="00"> + <availableFormats> + <numberFormat leadingDigits="2" + pattern="(2\d)(\d{3})(\d{3})">$1 $2 $3</numberFormat> + <numberFormat leadingDigits="8[24]" + pattern="(8[24])(\d{3})(\d{4})">$1 $2 $3</numberFormat> + <numberFormat leadingDigits="80" + pattern="(80\d)(\d{3})(\d{3})">$1 $2 $3</numberFormat> + </availableFormats> + <generalDesc> + <nationalNumberPattern>[28]\d{7,8}</nationalNumberPattern> + <possibleNumberPattern>\d{8,9}</possibleNumberPattern> + </generalDesc> + <fixedLine> + <nationalNumberPattern>2(?:[1346]\d|5[0-2]|[78][12]|93)\d{5}</nationalNumberPattern> + <possibleNumberPattern>\d{8}</possibleNumberPattern> + <exampleNumber>21123456</exampleNumber> + </fixedLine> + <mobile> + <nationalNumberPattern>8[24]\d{7}</nationalNumberPattern> + <possibleNumberPattern>\d{9}</possibleNumberPattern> + <exampleNumber>821234567</exampleNumber> + </mobile> + <tollFree> + <!-- Unsure of the length requirement on toll-free numbers, so using 9 + based on online examples.--> + <nationalNumberPattern>800\d{6}</nationalNumberPattern> + <possibleNumberPattern>\d{9}</possibleNumberPattern> + <exampleNumber>800123456</exampleNumber> + </tollFree> + <!-- The plan suggests 801 and 802 numbers are shared-cost numbers, and + numbers beginning with a 9 are premium rate, but no online examples can be + found of any of these so they are omitted for the time-being.--> </territory> <!-- Namibia --> <territory id="NA" countryCode="264" internationalPrefix="00" - nationalPrefix="0"> + nationalPrefix="0" nationalPrefixFormattingRule="$NP$FG"> + <availableFormats> + <numberFormat leadingDigits="8[15]" + pattern="(8\d)(\d{3})(\d{4})">$1 $2 $3</numberFormat> + <!-- This overlaps by necessity with the next pattern, so as it is more + specific, it is listed first. The area code is actually 632532, but + leadingDigits length is limited to 4.--> + <numberFormat leadingDigits="6325" pattern="(632532)(\d{2,4})">$1 $2</numberFormat> + <numberFormat leadingDigits="6(?:1|[245][1-7]|3[125-7]|6[1256]|7[1236])" + pattern="(6\d)(\d{2,3})(\d{4})">$1 $2 $3</numberFormat> + <!-- Another overlap pattern - this one is for shorter numbers. --> + <numberFormat leadingDigits="6(?:3[12567]|5[3-5]|6[1256]|7[1236])" + pattern="(6\d)(\d{4,5})">$1 $2</numberFormat> + <numberFormat leadingDigits="6[2356]8" pattern="(6\d{2})(\d{4,6})">$1 $2</numberFormat> + <numberFormat leadingDigits="6(?:342|6[34]|751)" + pattern="(6\d{3})(\d{4,5})">$1 $2</numberFormat> + <numberFormat leadingDigits="88" + pattern="(88)(\d{3})(\d{3})">$1 $2 $3</numberFormat> + </availableFormats> + <generalDesc> + <nationalNumberPattern>[68]\d{5,9}</nationalNumberPattern> + <possibleNumberPattern>\d{4,10}</possibleNumberPattern> + </generalDesc> + <fixedLine> + <nationalNumberPattern>6(?:1(?:[136]|2\d?)\d|2(?:[25]\d?|[134678])\d|3(?:2\d{0,3}|4\d{1,2}|[135-8]\d?)|4(?:[13-8]\d|2\d{1,2})|(?:5(?:[16-7]\d|[3-58]\d?|2\d{1,2}))|6\d{0,4}|7\d{0,3})\d{4}</nationalNumberPattern> + <exampleNumber>612012345</exampleNumber> + </fixedLine> + <mobile> + <nationalNumberPattern>8(?:1(?:1[0-2]|[23]\d|50)|5\d{2})\d{5}</nationalNumberPattern> + <possibleNumberPattern>\d{9}</possibleNumberPattern> + <exampleNumber>811012345</exampleNumber> + </mobile> + <voip> + <nationalNumberPattern>88\d{6}</nationalNumberPattern> + <possibleNumberPattern>\d{8}</possibleNumberPattern> + <exampleNumber>88123456</exampleNumber> + </voip> </territory> <!-- New Caledonia (Territoire français d'outre-mer) --> @@ -3756,23 +4400,28 @@ <!-- http://en.wikipedia.org/wiki/%2B675 --> <territory id="PG" countryCode="675" internationalPrefix="00"> <availableFormats> - <numberFormat leadingDigits="[1-689]|73" pattern="(\d{3})(\d{4})">$1 $2</numberFormat> - <numberFormat leadingDigits="7[126]" - pattern="(7[126]\d)(\d{2})(\d{3})">$1 $2 $3</numberFormat> + <numberFormat leadingDigits="[1-689]" pattern="(\d{3})(\d{4})">$1 $2</numberFormat> + <numberFormat leadingDigits="7[1-36]" + pattern="(7[1-36]\d)(\d{2})(\d{3})">$1 $2 $3</numberFormat> </availableFormats> <generalDesc> <nationalNumberPattern>[1-9]\d{6,7}</nationalNumberPattern> <possibleNumberPattern>\d{7,8}</possibleNumberPattern> </generalDesc> <fixedLine> - <nationalNumberPattern>(?:3\d|47|[56]4|73|85|9[78])\d{5}</nationalNumberPattern> + <!-- Fixed line patterns are from the numbering plan, with additions for + 4XX since many numbers in the yellow pages seem to be outside the + 47X range prescribed by the plan.--> + <nationalNumberPattern>(?:3\d{2}|4[257]\d|5[34]\d|6[24]9|85[02-46-9]|9[78]\d)\d{4}</nationalNumberPattern> <possibleNumberPattern>\d{7}</possibleNumberPattern> <exampleNumber>3123456</exampleNumber> </fixedLine> <mobile> - <nationalNumberPattern>(?:6[357-9]|7[126]\d)\d{5}</nationalNumberPattern> + <!-- Mobile number patterns from the numbering plan are included here, + as well as 68x from wikipedia.--> + <nationalNumberPattern>(?:68|7(?:[126]\d|3[34689]))\d{5}</nationalNumberPattern> <possibleNumberPattern>\d{7,8}</possibleNumberPattern> - <exampleNumber>6345678</exampleNumber> + <exampleNumber>6812345</exampleNumber> </mobile> <tollFree> <nationalNumberPattern>180\d{4}</nationalNumberPattern> @@ -4187,15 +4836,19 @@ </generalDesc> <fixedLine> <nationalNumberPattern>25\d{7}</nationalNumberPattern> + <exampleNumber>250123456</exampleNumber> </fixedLine> <mobile> <nationalNumberPattern>7[258]\d{7}</nationalNumberPattern> + <exampleNumber>720123456</exampleNumber> </mobile> <tollFree> <nationalNumberPattern>800\d{6}</nationalNumberPattern> + <exampleNumber>800123456</exampleNumber> </tollFree> <premiumRate> <nationalNumberPattern>900\d{6}</nationalNumberPattern> + <exampleNumber>900123456</exampleNumber> </premiumRate> </territory> @@ -4474,8 +5127,23 @@ </territory> <!-- Sao Tome and Principe --> - <territory id="ST" countryCode="239" internationalPrefix="00" - nationalPrefix="0"> + <!-- http://www.itu.int/oth/T02020000B6/en --> + <territory id="ST" countryCode="239" internationalPrefix="00"> + <availableFormats> + <numberFormat pattern="(\d{3})(\d{4})">$1 $2</numberFormat> + </availableFormats> + <generalDesc> + <nationalNumberPattern>[29]\d{6}</nationalNumberPattern> + <possibleNumberPattern>\d{7}</possibleNumberPattern> + </generalDesc> + <fixedLine> + <nationalNumberPattern>22\d{5}</nationalNumberPattern> + <exampleNumber>2221234</exampleNumber> + </fixedLine> + <mobile> + <nationalNumberPattern>9[89]\d{5}</nationalNumberPattern> + <exampleNumber>9812345</exampleNumber> + </mobile> </territory> <!-- El Salvador --> @@ -4511,7 +5179,32 @@ </territory> <!-- Swaziland --> + <!-- http://www.itu.int/oth/T02020000C6/en --> + <!-- Note this plan is scheduled to change in April and again in August in + 2010 so should be updated at that time. --> <territory id="SZ" countryCode="268" internationalPrefix="00"> + <generalDesc> + <nationalNumberPattern>[2-7]\d{6,7}</nationalNumberPattern> + <possibleNumberPattern>\d{7,8}</possibleNumberPattern> + </generalDesc> + <availableFormats> + <numberFormat leadingDigits="[2-6]" + pattern="(\d{3})(\d{4})">$1 $2</numberFormat> + <numberFormat leadingDigits="7" + pattern="(\d{4})(\d{4})">$1 $2</numberFormat> + </availableFormats> + <fixedLine> + <!-- The leading optional 2 is because future changes to the fixed-line + plan will be made by prepending a two to fixed-line numbers. --> + <nationalNumberPattern>2?(?:2(?:0[07]|[13]7|2[57])|3(?:0[34]|[1278]3|3[23]|[46][34])|(?:40[4-69]|16|2[12]|3[57]|[4578]2|67)|5(?:0[5-7]|1[6-9]|[23][78]|48|5[01]))\d{4}</nationalNumberPattern> + <exampleNumber>2171234</exampleNumber> + </fixedLine> + <mobile> + <!-- This covers both current numbers and the new proposed numbers due + to be introduced in April. --> + <nationalNumberPattern>(?:6|7[67])\d{6}</nationalNumberPattern> + <exampleNumber>6012345</exampleNumber> + </mobile> </territory> <!-- Turks and Caicos Islands --> @@ -4549,7 +5242,29 @@ </territory> <!-- Chad --> - <territory id="TD" countryCode="235" internationalPrefix="15"> + <!-- http://www.itu.int/oth/T0202000029/en --> + <!-- The international prefix includes 16 as the international manual + exchange. --> + <territory id="TD" countryCode="235" preferredInternationalPrefix="00" + internationalPrefix="00|16"> + <availableFormats> + <numberFormat + pattern="([2369]\d{2})(\d{2})(\d{2})">$1 $2 $3</numberFormat> + </availableFormats> + <generalDesc> + <nationalNumberPattern>[2369]\d{6}</nationalNumberPattern> + <possibleNumberPattern>\d{7}</possibleNumberPattern> + </generalDesc> + <fixedLine> + <nationalNumberPattern>2(?:5[0-4]|6[89])\d{4}</nationalNumberPattern> + <exampleNumber>2511234</exampleNumber> + </fixedLine> + <mobile> + <!-- The mobile ranges have been relaxed from the national numbering + plan following evidence from online numbers. --> + <nationalNumberPattern>(?:3[0-7]|6[27]|9\d)\d{5}</nationalNumberPattern> + <exampleNumber>6201234</exampleNumber> + </mobile> </territory> <!-- French Southern Territories --> @@ -4558,7 +5273,24 @@ </territory> <!-- Togo --> + <!-- http://www.itu.int/oth/T02020000D1/en --> <territory id="TG" countryCode="228" internationalPrefix="00"> + <availableFormats> + <numberFormat pattern="(\d{3})(\d{2})(\d{2})">$1 $2 $3</numberFormat> + </availableFormats> + <generalDesc> + <nationalNumberPattern>[02-9]\d{6}</nationalNumberPattern> + <possibleNumberPattern>\d{7}</possibleNumberPattern> + </generalDesc> + <fixedLine> + <nationalNumberPattern>(?:2[2-7]|3[23]|44|55|66|77)\d{5}</nationalNumberPattern> + <exampleNumber>2212345</exampleNumber> + </fixedLine> + <mobile> + <!-- Added prefix 09 because many mobile numbers were found with this.--> + <nationalNumberPattern>(?:0[1-9]|7[56]|8[1-7]|9\d)\d{5}</nationalNumberPattern> + <exampleNumber>0112345</exampleNumber> + </mobile> </territory> <!-- Thailand --> @@ -5069,6 +5801,10 @@ <numberFormat leadingDigits="[48]" pattern="([48])(\d{4})(\d{4})">$1 $2 $3</numberFormat> <numberFormat leadingDigits="2[025-79]|3[0136-9]|5[2-9]|6[0-46-9]|7[02-79]" pattern="([235-7]\d)(\d{4})(\d{3})">$1 $2 $3</numberFormat> + <numberFormat leadingDigits="80" + pattern="(80)(\d{5})">$1 $2</numberFormat> + <numberFormat leadingDigits="693" + pattern="(69[3-5])(\d{5})">$1 $2</numberFormat> <numberFormat leadingDigits="2[1348]|3[25]|5[01]|65|7[18]" pattern="([235-7]\d{2})(\d{4})(\d{3})">$1 $2 $3</numberFormat> <numberFormat leadingDigits="9" @@ -5079,16 +5815,16 @@ pattern="(1[89]00)(\d{4,6})">$1 $2</numberFormat> </availableFormats> <generalDesc> - <nationalNumberPattern>[1-9]\d{6,9}</nationalNumberPattern> + <nationalNumberPattern>8\d{5,8}|[1-79]\d{7,9}</nationalNumberPattern> <possibleNumberPattern>\d{7,10}</possibleNumberPattern> </generalDesc> <fixedLine> - <nationalNumberPattern>[2-8]\d{6,9}</nationalNumberPattern> + <nationalNumberPattern>(?:2(?:[025-79]|1[0189]|[348][01])|3(?:[0136-9]|[25][01])|[48]\d|5(?:[01][01]|[2-9])|6(?:[0-46-8]|5[01])|7(?:[02-79]|[18][01]))\d{7}|(?:80|69[3-5])\d{5}</nationalNumberPattern> <possibleNumberPattern>\d{7,10}</possibleNumberPattern> - <exampleNumber>2123456</exampleNumber> + <exampleNumber>2101234567</exampleNumber> </fixedLine> <mobile> - <nationalNumberPattern>(?:9[0-8]|1(?:2[1-369]|6[46-9]|99))\d{7}</nationalNumberPattern> + <nationalNumberPattern>(?:9[0-8]|1(?:2\d|6[46-9]|99))\d{7}</nationalNumberPattern> <possibleNumberPattern>\d{9,10}</possibleNumberPattern> <exampleNumber>912345678</exampleNumber> </mobile> @@ -5182,8 +5918,32 @@ </territory> <!-- Mayotte --> + <!-- Some information at + http://en.wikipedia.org/wiki/Telephone_numbers_in_France - most from + collection of internet data. + http://www.comores-online.com/mwezinet/internet/262.htm verifies the + fixed-line prefixes, but the mobile prefixes listed here seem out of date. + --> <territory id="YT" countryCode="262" internationalPrefix="00" - nationalPrefix="0"> + nationalPrefix="0" nationalPrefixFormattingRule="$NP$FG"> + <!-- Formatting as per La Réunion. --> + <generalDesc> + <nationalNumberPattern>[268]\d{8}</nationalNumberPattern> + <possibleNumberPattern>\d{9}</possibleNumberPattern> + </generalDesc> + <fixedLine> + <nationalNumberPattern>2696[0-4]\d{4}</nationalNumberPattern> + <exampleNumber>269601234</exampleNumber> + </fixedLine> + <mobile> + <nationalNumberPattern>639\d{6}</nationalNumberPattern> + <exampleNumber>639123456</exampleNumber> + </mobile> + <!-- Same as in France. --> + <tollFree> + <nationalNumberPattern>80\d{7}</nationalNumberPattern> + <exampleNumber>801234567</exampleNumber> + </tollFree> </territory> <!-- South Africa --> @@ -5225,9 +5985,25 @@ </voip> </territory> - <!--Zambia --> + <!-- Zambia --> + <!-- http://www.itu.int/oth/T02020000E8/en --> <territory id="ZM" countryCode="260" internationalPrefix="00" - nationalPrefix="0"> + nationalPrefix="0" nationalPrefixFormattingRule="$NP$FG"> + <availableFormats> + <numberFormat pattern="([29]\d)(\d{7})">$1 $2</numberFormat> + </availableFormats> + <generalDesc> + <nationalNumberPattern>[29]\d{8}</nationalNumberPattern> + <possibleNumberPattern>\d{9}</possibleNumberPattern> + </generalDesc> + <fixedLine> + <nationalNumberPattern>21[1-8]\d{6}</nationalNumberPattern> + <exampleNumber>211234567</exampleNumber> + </fixedLine> + <mobile> + <nationalNumberPattern>9(?:55|66|7[7-9])\d{6}</nationalNumberPattern> + <exampleNumber>955123456</exampleNumber> + </mobile> </territory> <!-- Zimbabwe --> diff --git a/java/resources/com/google/i18n/phonenumbers/src/generated_files/PhoneNumberMetadataProto b/java/resources/com/google/i18n/phonenumbers/src/generated_files/PhoneNumberMetadataProto Binary files differindex 1c6227f1..2cad0648 100644..100755 --- a/java/resources/com/google/i18n/phonenumbers/src/generated_files/PhoneNumberMetadataProto +++ b/java/resources/com/google/i18n/phonenumbers/src/generated_files/PhoneNumberMetadataProto diff --git a/java/src/com/google/i18n/phonenumbers/AsYouTypeFormatter.java b/java/src/com/google/i18n/phonenumbers/AsYouTypeFormatter.java index 4e093572..12bb9468 100644 --- a/java/src/com/google/i18n/phonenumbers/AsYouTypeFormatter.java +++ b/java/src/com/google/i18n/phonenumbers/AsYouTypeFormatter.java @@ -16,8 +16,8 @@ package com.google.i18n.phonenumbers; -import com.google.i18n.phonenumbers.Phonemetadata.PhoneMetadata; import com.google.i18n.phonenumbers.Phonemetadata.NumberFormat; +import com.google.i18n.phonenumbers.Phonemetadata.PhoneMetadata; import java.util.ArrayList; import java.util.List; @@ -42,10 +42,11 @@ public class AsYouTypeFormatter { private String formattingTemplate; private StringBuffer accruedInput; private StringBuffer accruedInputWithoutFormatting; - private boolean ableToFormat; + private boolean ableToFormat = true; + private boolean isInternationalFormatting = false; private final PhoneNumberUtil phoneUtil = PhoneNumberUtil.getInstance(); private String defaultCountry; - private PhoneMetadata defaultMetaData; + private Phonemetadata.PhoneMetadata defaultMetaData; private PhoneMetadata currentMetaData; // The digits that have not been entered yet will be represented by a \u2008, the punctuation @@ -69,7 +70,6 @@ public class AsYouTypeFormatter { accruedInputWithoutFormatting = new StringBuffer(); currentOutput = new StringBuffer(); prefixBeforeNationalNumber = new StringBuffer(); - ableToFormat = true; nationalNumber = new StringBuffer(); defaultCountry = regionCode; initializeCountrySpecificInfo(defaultCountry); @@ -101,7 +101,10 @@ public class AsYouTypeFormatter { private List<NumberFormat> getAvailableFormats(String leadingFourDigits) { List<NumberFormat> matchedList = new ArrayList<NumberFormat>(); - List<NumberFormat> formatList = currentMetaData.getNumberFormatList(); + List<NumberFormat> formatList = + (isInternationalFormatting && currentMetaData.getIntlNumberFormatCount() > 0) + ? currentMetaData.getIntlNumberFormatList() + : currentMetaData.getNumberFormatList(); for (NumberFormat format : formatList) { if (format.hasLeadingDigits()) { Pattern leadingDigitsPattern = Pattern.compile(format.getLeadingDigits()); @@ -164,6 +167,7 @@ public class AsYouTypeFormatter { prefixBeforeNationalNumber = new StringBuffer(); nationalNumber = new StringBuffer(); ableToFormat = true; + isInternationalFormatting = false; if (!currentMetaData.equals(defaultMetaData)) { initializeCountrySpecificInfo(defaultCountry); } @@ -269,6 +273,7 @@ public class AsYouTypeFormatter { nationalNumber = new StringBuffer(); Matcher iddMatcher = internationalPrefix.matcher(accruedInputWithoutFormatting); if (iddMatcher.lookingAt()) { + isInternationalFormatting = true; int startOfCountryCode = iddMatcher.end(); StringBuffer numberIncludeCountryCode = new StringBuffer(accruedInputWithoutFormatting.substring(startOfCountryCode)); diff --git a/java/src/com/google/i18n/phonenumbers/PhoneNumberUtil.java b/java/src/com/google/i18n/phonenumbers/PhoneNumberUtil.java index 96e82081..073a45ac 100644 --- a/java/src/com/google/i18n/phonenumbers/PhoneNumberUtil.java +++ b/java/src/com/google/i18n/phonenumbers/PhoneNumberUtil.java @@ -18,6 +18,7 @@ package com.google.i18n.phonenumbers; import com.google.common.annotations.VisibleForTesting; import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; import com.google.i18n.phonenumbers.Phonemetadata.NumberFormat; import com.google.i18n.phonenumbers.Phonemetadata.PhoneMetadata; import com.google.i18n.phonenumbers.Phonemetadata.PhoneMetadataCollection; @@ -49,9 +50,9 @@ import java.util.regex.Pattern; * @author Lara Rennie */ public class PhoneNumberUtil { - // The maximum and minimum length of the national significant number. - private static final int MAX_LENGTH_FOR_NSN = 15; + // The minimum and maximum length of the national significant number. private static final int MIN_LENGTH_FOR_NSN = 3; + private static final int MAX_LENGTH_FOR_NSN = 15; private static final String META_DATA_FILE = "/com/google/i18n/phonenumbers/src/generated_files/PhoneNumberMetadataProto"; private static final Logger LOGGER = Logger.getLogger(PhoneNumberUtil.class.getName()); @@ -154,6 +155,17 @@ public class PhoneNumberUtil { .putAll(DIGIT_MAPPINGS) .build(); + // A list of all country codes where national significant numbers (excluding any national prefix) + // exist that start with a leading zero. + private static final Set<Integer> LEADING_ZERO_COUNTRIES = + new ImmutableSet.Builder<Integer>() + .add(39) // Italy + .add(225) // Cote d'Ivoire + .add(228) // Togo + .add(240) // Equatorial Guinea + .add(241) // Gabon + .build(); + // Pattern that makes it easy to distinguish whether a country has a unique international dialing // prefix or not. If a country has a unique international prefix (e.g. 011 in USA), it will be // represented as a string that contains a sequence of ASCII digits. If there are multiple @@ -161,15 +173,15 @@ public class PhoneNumberUtil { // always contains character(s) other than ASCII digits. // Note this regex also includes tilde, which signals waiting for the tone. private static final Pattern UNIQUE_INTERNATIONAL_PREFIX = - Pattern.compile("[\\d]+([~\u2053\u223C\uFF5E][\\d]+)?"); + Pattern.compile("[\\d]+(?:[~\u2053\u223C\uFF5E][\\d]+)?"); // Regular expression of acceptable punctuation found in phone numbers. This excludes punctuation // found as a leading character only. // This consists of dash characters, white space characters, full stops, slashes, // square brackets, parentheses and tildes. It also includes the letter 'x' as that is found as a // placeholder for carrier information in some phone numbers. - private static final String VALID_PUNCTUATION = "[-x\u2010-\u2015\u2212\uFF0D-\uFF0F " + - "\u00A0\u200B\u2060\u3000()\uFF08\uFF09\uFF3B\uFF3D.\\[\\]/~\u2053\u223C\uFF5E]"; + private static final String VALID_PUNCTUATION = "-x\u2010-\u2015\u2212\uFF0D-\uFF0F " + + "\u00A0\u200B\u2060\u3000()\uFF08\uFF09\uFF3B\uFF3D.\\[\\]/~\u2053\u223C\uFF5E"; // Digits accepted in phone numbers private static final String VALID_DIGITS = @@ -199,16 +211,25 @@ public class PhoneNumberUtil { private static final String SECOND_NUMBER_START = "[\\\\/] *x"; private static final Pattern SECOND_NUMBER_START_PATTERN = Pattern.compile(SECOND_NUMBER_START); + // Regular expression of trailing characters that we want to remove. We remove all characters that + // are not alpha or numerical characters. The hash character is retained here, as it may signify + // the previous block was an extension. + private static final String UNWANTED_END_CHARS = "[[\\P{N}&&\\P{L}]&&[^#]]+$"; + private static final Pattern UNWANTED_END_CHAR_PATTERN = Pattern.compile(UNWANTED_END_CHARS); + + // We use this pattern to check if the phone number has at least three letters in it - if so, then + // we treat it as a number where some phone-number digits are represented by letters. + private static final Pattern VALID_ALPHA_PHONE_PATTERN = Pattern.compile("(?:.*?[A-Za-z]){3}.*"); + // Regular expression of viable phone numbers. This is location independent. Checks we have at // least three leading digits, and only valid punctuation, alpha characters and - // digits in the phone number. Does not include extension data - this is read in from the - // PhoneNumberMetaData.xml file at initialisation time. + // digits in the phone number. Does not include extension data. // The symbol 'x' is allowed here as valid punctuation since it is often used as a placeholder for // carrier codes, for example in Brazilian phone numbers. // Corresponds to the following: // plus_sign?([punctuation]*[digits]){3,}([punctuation]|[digits]|[alpha])* private static final String VALID_PHONE_NUMBER = - "[" + PLUS_CHARS + "]?(?:" + VALID_PUNCTUATION + "*[" + VALID_DIGITS + "]){3,}[" + + "[" + PLUS_CHARS + "]?(?:[" + VALID_PUNCTUATION + "]*[" + VALID_DIGITS + "]){3,}[" + VALID_ALPHA + VALID_PUNCTUATION + VALID_DIGITS + "]*"; // Default extension prefix to use when formatting. This will be put in front of any extension @@ -225,9 +246,9 @@ public class PhoneNumberUtil { // the extension is written with a hash at the end, such as "- 503#". // Note that the only capturing groups should be around the digits that you want to capture as // part of the extension, or else parsing will fail! - private static final String KNOWN_EXTN_PATTERNS = "[ \\u00A0\\t,]*(?:ext(?:ensio)?n?|" + - "\\uFF45\\uFF58\\uFF54\\uFF4E?|[,x\\uFF58#\\uFF03~\\uFF5E]|int|\\uFF49\\uFF4E\\uFF54)" + - "[:\\.\\uFF0E]?[ \\u00A0\\t,]*([" + VALID_DIGITS + "]{1,7})|[- ]+([" + VALID_DIGITS + + private static final String KNOWN_EXTN_PATTERNS = "[ \u00A0\\t,]*(?:ext(?:ensio)?n?|" + + "\uFF45\uFF58\uFF54\uFF4E?|[,x\uFF58#\uFF03~\uFF5E]|int|\uFF49\uFF4E\uFF54)" + + "[:\\.\uFF0E]?[ \u00A0\\t,]*([" + VALID_DIGITS + "]{1,7})|[- ]+([" + VALID_DIGITS + "]{1,5})#"; // Regexp of all known extension prefixes used by different countries followed by 1 or more valid @@ -239,7 +260,7 @@ public class PhoneNumberUtil { // We append optionally the extension pattern to the end here, as a valid phone number may // have an extension prefix appended, followed by 1 or more digits. private static final Pattern VALID_PHONE_NUMBER_PATTERN = - Pattern.compile(VALID_PHONE_NUMBER + "(?:" + EXTN_PATTERN + ")?", + Pattern.compile(VALID_PHONE_NUMBER + "(?:" + KNOWN_EXTN_PATTERNS + ")?", Pattern.UNICODE_CASE | Pattern.CASE_INSENSITIVE); private static PhoneNumberUtil instance = null; @@ -367,8 +388,12 @@ public class PhoneNumberUtil { */ @VisibleForTesting static String extractPossibleNumber(String number) { - // Remove leading and trailing whitespace. - number = number.trim(); + // Remove trailing non-alpha non-numerical characters. + Matcher trailingCharsMatcher = UNWANTED_END_CHAR_PATTERN.matcher(number); + if (trailingCharsMatcher.find()) { + number = number.substring(0, trailingCharsMatcher.start()); + LOGGER.log(Level.FINER, "Stripped trailing characters: " + number); + } Matcher m = VALID_START_CHAR_PATTERN.matcher(number); if (m.find()) { number = number.substring(m.start()); @@ -417,7 +442,8 @@ public class PhoneNumberUtil { * @return the normalized string version of the phone number */ static String normalize(String number) { - if (number.matches("(?:.*?[A-Za-z]){3}.*")) { + Matcher m = VALID_ALPHA_PHONE_PATTERN.matcher(number); + if (m.matches()) { return normalizeHelper(number, ALL_NORMALIZATION_MAPPINGS, true); } else { return normalizeHelper(number, DIGIT_MAPPINGS, true); @@ -438,7 +464,7 @@ public class PhoneNumberUtil { /** * Normalizes a string of characters representing a phone number. This converts wide-ascii and - * arabic-indic numerals to European numerals, and strips punctuation and alpha characters, + * arabic-indic numerals to European numerals, and strips punctuation and alpha characters. * * @param number a string of characters representing a phone number * @return the normalized string version of the phone number @@ -503,15 +529,6 @@ public class PhoneNumberUtil { instance = null; } - @VisibleForTesting - PhoneMetadata getPhoneMetadata(String regionCode) { - PhoneMetadata metadata = countryToMetadataMap.get(regionCode); - // makes a defensive copy - PhoneMetadata.Builder metadataCopy = metadata.newBuilder(); - metadataCopy.mergeFrom(metadata); - return metadataCopy.build(); - } - /** * Convenience method to enable tests to get a list of what countries the library has metadata * for. @@ -541,8 +558,8 @@ public class PhoneNumberUtil { } /** - * Helper function to check region code is not unknown or null. The number supplied is used only - * for the resultant log message. + * Helper function to check region code is not unknown or null. The countryCode and number + * supplied is used only for the resultant log message. */ private boolean isValidRegionCode(String regionCode, int countryCode, String number) { if (regionCode == null || regionCode.equals("ZZ")) { @@ -605,8 +622,9 @@ public class PhoneNumberUtil { PhoneNumberFormat numberFormat, List<NumberFormat> userDefinedFormats) { int countryCode = number.getCountryCode(); - // For performance reasons, we use US to represent NANPA countries here. This means that - // the extension symbol will be chosen from the US metadata. + // Note getRegionCodeForCountryCode() is used because formatting information for countries which + // share a country code is contained by only one country for performance reasons. For example, + // for NANPA countries it will be contained in the metadata for US. String regionCode = getRegionCodeForCountryCode(countryCode); String nationalSignificantNumber = getUnformattedNationalNumber(number); if (!isValidRegionCode(regionCode, countryCode, nationalSignificantNumber)) { @@ -662,7 +680,7 @@ public class PhoneNumberUtil { return format(number, PhoneNumberFormat.INTERNATIONAL); } int countryCode = number.getCountryCode(); - if (countryCode == NANPA_COUNTRY_CODE && nanpaCountries.contains(countryCallingFrom)) { + if (countryCode == NANPA_COUNTRY_CODE && isNANPACountry(countryCallingFrom)) { // For NANPA countries, return the national format for these countries but prefix it with the // country code. return countryCode + " " + format(number, PhoneNumberFormat.NATIONAL); @@ -736,9 +754,9 @@ public class PhoneNumberUtil { // number. There have been plans to migrate landline numbers to start with the digit two since // December 2000, but it has not yet happened. // See http://en.wikipedia.org/wiki/%2B39 for more details. - // Cote d'Ivoire also uses this for some of their mobile numbers. + // Other countries such as Cote d'Ivoire and Gabon use this for their mobile numbers. StringBuffer nationalNumber = new StringBuffer( - ((number.getCountryCode() == 39 || number.getCountryCode() == 225) && + (isLeadingZeroCountry(number.getCountryCode()) && number.hasItalianLeadingZero() && number.getItalianLeadingZero()) ? "0" : "" @@ -903,8 +921,7 @@ public class PhoneNumberUtil { if (!isValidRegionCode(regionCode, number.getCountryCode(), nationalSignificantNumber)) { return PhoneNumberType.UNKNOWN; } - PhoneMetadata metadata = getMetadataForRegion(regionCode); - return getNumberTypeHelper(nationalSignificantNumber, metadata); + return getNumberTypeHelper(nationalSignificantNumber, getMetadataForRegion(regionCode)); } private PhoneNumberType getNumberTypeHelper(String nationalNumber, PhoneMetadata metadata) { @@ -972,13 +989,8 @@ public class PhoneNumberUtil { } private boolean isNumberMatchingDesc(String nationalNumber, PhoneNumberDesc numberDesc) { - String possiblePattern = numberDesc.getPossibleNumberPattern(); - if (!nationalNumber.matches(possiblePattern)) { - return false; - } - - String validPattern = numberDesc.getNationalNumberPattern(); - return nationalNumber.matches(validPattern); + return nationalNumber.matches(numberDesc.getPossibleNumberPattern()) && + nationalNumber.matches(numberDesc.getNationalNumberPattern()); } /** @@ -1016,7 +1028,7 @@ public class PhoneNumberUtil { PhoneNumberDesc generalNumDesc = metadata.getGeneralDesc(); String nationalSignificantNumber = getUnformattedNationalNumber(number); - // For countries where we don't have meta-data for PhoneNumberDesc, we treat any number passed + // For countries where we don't have metadata for PhoneNumberDesc, we treat any number passed // in as a valid number if its national significant number is between the minimum and maximum // lengths defined by ITU for a national significant number. if (!generalNumDesc.hasNationalNumberPattern()) { @@ -1037,7 +1049,6 @@ public class PhoneNumberUtil { */ public String getRegionCodeForNumber(PhoneNumber number) { int countryCode = number.getCountryCode(); - String regionCode; switch (countryCode) { case NANPA_COUNTRY_CODE: // Override this and try the US case first, since it is more likely than other countries, @@ -1047,14 +1058,11 @@ public class PhoneNumberUtil { } Set<String> nanpaExceptUS = new HashSet<String>(nanpaCountries); nanpaExceptUS.remove("US"); - regionCode = getRegionCodeForNumberFromRegionList(number, nanpaExceptUS); - return regionCode; + return getRegionCodeForNumberFromRegionList(number, nanpaExceptUS); case RUSSIAN_FED_COUNTRY_CODE: - regionCode = getRegionCodeForNumberFromRegionList(number, russiaFederationCountries); - return regionCode; + return getRegionCodeForNumberFromRegionList(number, russiaFederationCountries); case FRENCH_INDIAN_OCEAN_COUNTRY_CODE: - regionCode = getRegionCodeForNumberFromRegionList(number, frenchIndianOceanTerritories); - return regionCode; + return getRegionCodeForNumberFromRegionList(number, frenchIndianOceanTerritories); default: return getRegionCodeForCountryCode(countryCode); } @@ -1064,8 +1072,8 @@ public class PhoneNumberUtil { Set<String> regionCodes) { String nationalNumber = String.valueOf(number.getNationalNumber()); for (String regionCode : regionCodes) { - PhoneMetadata metadata = getMetadataForRegion(regionCode); - if (getNumberTypeHelper(nationalNumber, metadata) != PhoneNumberType.UNKNOWN) { + if (getNumberTypeHelper(nationalNumber, getMetadataForRegion(regionCode)) != + PhoneNumberType.UNKNOWN) { return regionCode; } } @@ -1095,17 +1103,21 @@ public class PhoneNumberUtil { return 0; } PhoneMetadata metadata = getMetadataForRegion(regionCode); + if (metadata == null) { + LOGGER.log(Level.SEVERE, "Unsupported country code provided."); + return 0; + } return metadata.getCountryCode(); } /** - * Gets a set which contains all the countries under the North American Numbering Plan + * Check if a country is one of the countries under the North American Numbering Plan * Administration (NANPA). * - * @return the set that contains the countries under NANPA + * @return true if regionCode is one of the countries under NANPA */ - public Set<String> getNANPACountries() { - return new HashSet<String>(nanpaCountries); + public boolean isNANPACountry(String regionCode) { + return nanpaCountries.contains(regionCode); } /** @@ -1119,6 +1131,14 @@ public class PhoneNumberUtil { } /** + * Check whether countryCode represents the country calling code from a country whose national + * significant number could contain a leading zero. An example of such a country is Italy. + */ + public static boolean isLeadingZeroCountry(int countryCode) { + return LEADING_ZERO_COUNTRIES.contains(countryCode); + } + + /** * Check whether a phone number is a possible number. It provides a more lenient check than * isValidNumber in the following sense: * 1. It only checks the length of phone numbers. In particular, it doesn't check starting @@ -1139,7 +1159,7 @@ public class PhoneNumberUtil { * @return a ValidationResult object which indicates whether the number is possible */ public ValidationResult isPossibleNumberWithReason(PhoneNumber number) { - String nationalNumber = String.valueOf(number.getNationalNumber()); + String nationalNumber = getUnformattedNationalNumber(number); int countryCode = number.getCountryCode(); // Note: For Russian Fed and NANPA numbers, we just use the rules from the default region (US or // Russia) since the getRegionCodeForNumber will not work if the number is possible but not @@ -1313,7 +1333,7 @@ public class PhoneNumberUtil { // begin with 0. Matcher digitMatcher = CAPTURING_DIGIT_PATTERN.matcher(number.substring(matchEnd)); if (digitMatcher.find()) { - String normalizedGroup = normalize(digitMatcher.group(1)); + String normalizedGroup = normalizeHelper(digitMatcher.group(1), DIGIT_MAPPINGS, true); if (normalizedGroup.equals("0")) { return false; } @@ -1456,7 +1476,31 @@ public class PhoneNumberUtil { throw new NumberParseException(NumberParseException.ErrorType.INVALID_COUNTRY_CODE, "No default country was supplied."); } - return parseHelper(numberToParse, defaultCountry); + return parseHelper(numberToParse, defaultCountry, false); + } + + /** + * Parses a string and returns it in proto buffer format. This method differs from parse() in that + * it always populates the raw_input field of the protocol buffer with numberToParse. + * + * @param numberToParse number that we are attempting to parse. This can contain formatting + * such as +, ( and -, as well as a phone number extension. + * @param defaultCountry the ISO 3166-1 two-letter country code that denotes the country that + * we are expecting the number to be from. This is only used + * if the number being parsed is not written in international format. + * The country code for the number in this case would be stored as that + * of the default country supplied. + * @return a phone number proto buffer filled with the parsed number + * @throws NumberParseException if the string is not considered to be a viable phone number or if + * no default country was supplied + */ + public PhoneNumber parseAndKeepRawInput(String numberToParse, String defaultCountry) + throws NumberParseException { + if (defaultCountry == null || defaultCountry.equals("ZZ")) { + throw new NumberParseException(NumberParseException.ErrorType.INVALID_COUNTRY_CODE, + "No default country was supplied."); + } + return parseHelper(numberToParse, defaultCountry, true); } /** @@ -1489,7 +1533,8 @@ public class PhoneNumberUtil { * parse() method, with the exception that it allows the default country to be null, for use by * isNumberMatch(). */ - private PhoneNumber parseHelper(String numberToParse, String defaultCountry) + private PhoneNumber parseHelper(String numberToParse, String defaultCountry, + Boolean keepRawInput) throws NumberParseException { // Extract a possible number from the string passed in (this strips leading characters that // could not be the start of a phone number.) @@ -1500,6 +1545,9 @@ public class PhoneNumberUtil { } PhoneNumber.Builder phoneNumber = PhoneNumber.newBuilder(); + if (keepRawInput) { + phoneNumber.setRawInput(numberToParse); + } StringBuffer nationalNumber = new StringBuffer(number); // Attempt to parse extension first, since it doesn't require country-specific data and we want // to have the non-normalised number here. @@ -1541,8 +1589,8 @@ public class PhoneNumberUtil { validNumberPattern); } phoneNumber.setCountryCode(countryCode); - // The ItalianLeadingZero is valid only for numbers from IT and CI. - if ((countryCode == 39 || countryCode == 225) && normalizedNationalNumber.charAt(0) == '0') { + if (isLeadingZeroCountry(countryCode) && + normalizedNationalNumber.charAt(0) == '0') { phoneNumber.setItalianLeadingZero(true); } int lengthOfNationalNumber = normalizedNationalNumber.length(); @@ -1586,8 +1634,10 @@ public class PhoneNumberUtil { firstNumber.mergeFrom(firstNumberIn); PhoneNumber.Builder secondNumber = PhoneNumber.newBuilder(); secondNumber.mergeFrom(secondNumberIn); - // First clear any empty-string extensions so that we can use the proto-buffer equality method. - + // First clear raw_input field and any empty-string extensions so that we can use the + // proto-buffer equality method. + firstNumber.clearRawInput(); + secondNumber.clearRawInput(); if (firstNumber.hasExtension() && firstNumber.getExtension().equals("")) { firstNumber.clearExtension(); @@ -1611,17 +1661,12 @@ public class PhoneNumberUtil { if (firstNumberCountryCode != 0 && secondNumberCountryCode != 0) { if (areSameMessages(number1, number2)) { return MatchType.EXACT_MATCH; - } else if (firstNumberCountryCode == secondNumberCountryCode) { + } else if (firstNumberCountryCode == secondNumberCountryCode && + isNationalNumberSuffixOfTheOther(number1, number2)) { // A SHORT_NSN_MATCH occurs if there is a difference because of the presence or absence of // an 'Italian leading zero', the presence or absence of an extension, or one NSN being a // shorter variant of the other. - String firstNumberNationalNumber = String.valueOf(number1.getNationalNumber()); - String secondNumberNationalNumber = String.valueOf(number2.getNationalNumber()); - // Note that endsWith returns true if the numbers are equal. - if (firstNumberNationalNumber.endsWith(secondNumberNationalNumber) || - secondNumberNationalNumber.endsWith(firstNumberNationalNumber)) { - return MatchType.SHORT_NSN_MATCH; - } + return MatchType.SHORT_NSN_MATCH; } // This is not a match. return MatchType.NO_MATCH; @@ -1634,16 +1679,22 @@ public class PhoneNumberUtil { if (areSameMessages(newNumber, number2)) { return MatchType.NSN_MATCH; } - String firstNumberNationalNumber = String.valueOf(newNumber.getNationalNumber()); - String secondNumberNationalNumber = String.valueOf(number2.getNationalNumber()); - // Note that endsWith returns true if the numbers are equal. - if (firstNumberNationalNumber.endsWith(secondNumberNationalNumber) || - secondNumberNationalNumber.endsWith(firstNumberNationalNumber)) { + if (isNationalNumberSuffixOfTheOther(newNumber, number2)) { return MatchType.SHORT_NSN_MATCH; } return MatchType.NO_MATCH; } + // Returns true when one national number is the suffix of the other or both are the same. + private boolean isNationalNumberSuffixOfTheOther(PhoneNumber firstNumber, + PhoneNumber secondNumber) { + String firstNumberNationalNumber = String.valueOf(firstNumber.getNationalNumber()); + String secondNumberNationalNumber = String.valueOf(secondNumber.getNationalNumber()); + // Note that endsWith returns true if the numbers are equal. + return firstNumberNationalNumber.endsWith(secondNumberNationalNumber) || + secondNumberNationalNumber.endsWith(firstNumberNationalNumber); + } + /** * Takes two phone numbers as strings and compares them for equality. This is a convenience * wrapper for isNumberMatch(PhoneNumber firstNumber, PhoneNumber secondNumber). No default region @@ -1660,7 +1711,8 @@ public class PhoneNumberUtil { */ public MatchType isNumberMatch(String firstNumber, String secondNumber) throws NumberParseException { - return isNumberMatch(parseHelper(firstNumber, null), parseHelper(secondNumber, null)); + return isNumberMatch(parseHelper(firstNumber, null, false), + parseHelper(secondNumber, null, false)); } /** @@ -1677,6 +1729,6 @@ public class PhoneNumberUtil { */ public MatchType isNumberMatch(PhoneNumber firstNumber, String secondNumber) throws NumberParseException { - return isNumberMatch(firstNumber, parseHelper(secondNumber, null)); + return isNumberMatch(firstNumber, parseHelper(secondNumber, null, false)); } } diff --git a/java/src/com/google/i18n/phonenumbers/Phonenumber.java b/java/src/com/google/i18n/phonenumbers/Phonenumber.java index c3b50891..8ff78332 100644 --- a/java/src/com/google/i18n/phonenumbers/Phonenumber.java +++ b/java/src/com/google/i18n/phonenumbers/Phonenumber.java @@ -53,6 +53,13 @@ public final class Phonenumber { public boolean hasItalianLeadingZero() { return hasItalianLeadingZero; } public boolean getItalianLeadingZero() { return italianLeadingZero_; } + // optional string raw_input = 5; + public static final int RAW_INPUT_FIELD_NUMBER = 5; + private boolean hasRawInput; + private java.lang.String rawInput_ = ""; + public boolean hasRawInput() { return hasRawInput; } + public java.lang.String getRawInput() { return rawInput_; } + private void initFields() { } public final boolean isInitialized() { @@ -76,6 +83,9 @@ public final class Phonenumber { if (hasItalianLeadingZero()) { output.writeBool(4, getItalianLeadingZero()); } + if (hasRawInput()) { + output.writeString(5, getRawInput()); + } } private int memoizedSerializedSize = -1; @@ -100,6 +110,10 @@ public final class Phonenumber { size += com.google.protobuf.CodedOutputStream .computeBoolSize(4, getItalianLeadingZero()); } + if (hasRawInput()) { + size += com.google.protobuf.CodedOutputStream + .computeStringSize(5, getRawInput()); + } memoizedSerializedSize = size; return size; } @@ -256,6 +270,9 @@ public final class Phonenumber { if (other.hasItalianLeadingZero()) { setItalianLeadingZero(other.getItalianLeadingZero()); } + if (other.hasRawInput()) { + setRawInput(other.getRawInput()); + } return this; } @@ -290,6 +307,10 @@ public final class Phonenumber { setItalianLeadingZero(input.readBool()); break; } + case 42: { + setRawInput(input.readString()); + break; + } } } } @@ -370,6 +391,27 @@ public final class Phonenumber { return this; } + // optional string raw_input = 5; + public boolean hasRawInput() { + return result.hasRawInput(); + } + public java.lang.String getRawInput() { + return result.getRawInput(); + } + public Builder setRawInput(java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + result.hasRawInput = true; + result.rawInput_ = value; + return this; + } + public Builder clearRawInput() { + result.hasRawInput = false; + result.rawInput_ = getDefaultInstance().getRawInput(); + return this; + } + // @@protoc_insertion_point(builder_scope:i18n.phonenumbers.PhoneNumber) } diff --git a/java/src/com/google/i18n/phonenumbers/phonenumber.proto b/java/src/com/google/i18n/phonenumbers/phonenumber.proto index 42382746..27b5996f 100644 --- a/java/src/com/google/i18n/phonenumbers/phonenumber.proto +++ b/java/src/com/google/i18n/phonenumbers/phonenumber.proto @@ -50,6 +50,11 @@ message PhoneNumber { // phone numbers. For an Italian phone number, if its national (significant) number starts // with the digit zero, set this flag to true. optional bool italian_leading_zero = 4; + +// This field is used to store the raw input string containing phone numbers before it was +// canonicalized by the library. For example, it could be used to store alphanumerical numbers +// such as "1-800-GOOG-411". + optional string raw_input = 5; } // Examples diff --git a/java/test/com/google/i18n/phonenumbers/AsYouTypeFormatterTest.java b/java/test/com/google/i18n/phonenumbers/AsYouTypeFormatterTest.java index 6eb77f94..d464cd26 100644 --- a/java/test/com/google/i18n/phonenumbers/AsYouTypeFormatterTest.java +++ b/java/test/com/google/i18n/phonenumbers/AsYouTypeFormatterTest.java @@ -113,6 +113,25 @@ public class AsYouTypeFormatterTest extends TestCase { assertEquals("011 44 6 123 123 123", formatter.inputDigit('3')); formatter.clear(); + assertEquals("0", formatter.inputDigit('0')); + assertEquals("01", formatter.inputDigit('1')); + assertEquals("011", formatter.inputDigit('1')); + assertEquals("0115", formatter.inputDigit('5')); + assertEquals("01154", formatter.inputDigit('4')); + assertEquals("011 54 9", formatter.inputDigit('9')); + assertEquals("011 54 91", formatter.inputDigit('1')); + assertEquals("011 54 911", formatter.inputDigit('1')); + assertEquals("011 54 9 11 2\u2008\u2008\u2008 \u2008\u2008\u2008\u2008", + formatter.inputDigit('2')); + assertEquals("011 54 9 11 23\u2008\u2008 \u2008\u2008\u2008\u2008", formatter.inputDigit('3')); + assertEquals("011 54 9 11 231\u2008 \u2008\u2008\u2008\u2008", formatter.inputDigit('1')); + assertEquals("011 54 9 11 2312 \u2008\u2008\u2008\u2008", formatter.inputDigit('2')); + assertEquals("011 54 9 11 2312 1\u2008\u2008\u2008", formatter.inputDigit('1')); + assertEquals("011 54 9 11 2312 12\u2008\u2008", formatter.inputDigit('2')); + assertEquals("011 54 9 11 2312 123\u2008", formatter.inputDigit('3')); + assertEquals("011 54 9 11 2312 1234", formatter.inputDigit('4')); + + formatter.clear(); assertEquals("+", formatter.inputDigit('+')); assertEquals("+1", formatter.inputDigit('1')); assertEquals("+16", formatter.inputDigit('6')); @@ -229,4 +248,38 @@ public class AsYouTypeFormatterTest extends TestCase { assertEquals("030123", formatter.inputDigit('3')); assertEquals("0301234", formatter.inputDigit('4')); } + + public void testAsYouTypeFormatterAR() { + AsYouTypeFormatter formatter = phoneUtil.getAsYouTypeFormatter("AR"); + assertEquals("0", formatter.inputDigit('0')); + assertEquals("01", formatter.inputDigit('1')); + assertEquals("011", formatter.inputDigit('1')); + assertEquals("0117", formatter.inputDigit('7')); + assertEquals("01170", formatter.inputDigit('0')); + assertEquals("011 703\u2008-\u2008\u2008\u2008\u2008", formatter.inputDigit('3')); + assertEquals("011 7031-\u2008\u2008\u2008\u2008", formatter.inputDigit('1')); + assertEquals("011 7031-3\u2008\u2008\u2008", formatter.inputDigit('3')); + assertEquals("011 7031-30\u2008\u2008", formatter.inputDigit('0')); + assertEquals("011 7031-300\u2008", formatter.inputDigit('0')); + assertEquals("011 7031-3000", formatter.inputDigit('0')); + } + + public void testAsYouTypeFormatterARMobile() { + AsYouTypeFormatter formatter = phoneUtil.getAsYouTypeFormatter("AR"); + assertEquals("+", formatter.inputDigit('+')); + assertEquals("+5", formatter.inputDigit('5')); + assertEquals("+54", formatter.inputDigit('4')); + assertEquals("+549", formatter.inputDigit('9')); + assertEquals("+5491", formatter.inputDigit('1')); + assertEquals("+54 911", formatter.inputDigit('1')); + assertEquals("+54 9 11 2\u2008\u2008\u2008 \u2008\u2008\u2008\u2008", + formatter.inputDigit('2')); + assertEquals("+54 9 11 23\u2008\u2008 \u2008\u2008\u2008\u2008", formatter.inputDigit('3')); + assertEquals("+54 9 11 231\u2008 \u2008\u2008\u2008\u2008", formatter.inputDigit('1')); + assertEquals("+54 9 11 2312 \u2008\u2008\u2008\u2008", formatter.inputDigit('2')); + assertEquals("+54 9 11 2312 1\u2008\u2008\u2008", formatter.inputDigit('1')); + assertEquals("+54 9 11 2312 12\u2008\u2008", formatter.inputDigit('2')); + assertEquals("+54 9 11 2312 123\u2008", formatter.inputDigit('3')); + assertEquals("+54 9 11 2312 1234", formatter.inputDigit('4')); + } } diff --git a/java/test/com/google/i18n/phonenumbers/PhoneNumberUtilTest.java b/java/test/com/google/i18n/phonenumbers/PhoneNumberUtilTest.java index 0721fa61..746a3ed9 100644 --- a/java/test/com/google/i18n/phonenumbers/PhoneNumberUtilTest.java +++ b/java/test/com/google/i18n/phonenumbers/PhoneNumberUtilTest.java @@ -26,7 +26,6 @@ import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.List; -import java.util.Set; import java.util.regex.Pattern; /** @@ -65,7 +64,7 @@ public class PhoneNumberUtilTest extends TestCase { } public void testGetInstanceLoadUSMetadata() throws IOException { - PhoneMetadata metadata = phoneUtil.getPhoneMetadata("US"); + PhoneMetadata metadata = phoneUtil.getMetadataForRegion("US"); assertEquals("US", metadata.getId()); assertEquals(1, metadata.getCountryCode()); assertEquals("011", metadata.getInternationalPrefix()); @@ -86,7 +85,7 @@ public class PhoneNumberUtilTest extends TestCase { } public void testGetInstanceLoadDEMetadata() { - PhoneMetadata metadata = phoneUtil.getPhoneMetadata("DE"); + PhoneMetadata metadata = phoneUtil.getMetadataForRegion("DE"); assertEquals("DE", metadata.getId()); assertEquals(49, metadata.getCountryCode()); assertEquals("00", metadata.getInternationalPrefix()); @@ -105,7 +104,7 @@ public class PhoneNumberUtilTest extends TestCase { } public void testGetInstanceLoadARMetadata() { - PhoneMetadata metadata = phoneUtil.getPhoneMetadata("AR"); + PhoneMetadata metadata = phoneUtil.getMetadataForRegion("AR"); assertEquals("AR", metadata.getId()); assertEquals(54, metadata.getCountryCode()); assertEquals("00", metadata.getInternationalPrefix()); @@ -740,13 +739,15 @@ public class PhoneNumberUtilTest extends TestCase { public void testGetCountryCodeForRegion() { assertEquals(1, phoneUtil.getCountryCodeForRegion("US")); assertEquals(64, phoneUtil.getCountryCodeForRegion("NZ")); + assertEquals(0, phoneUtil.getCountryCodeForRegion(null)); + assertEquals(0, phoneUtil.getCountryCodeForRegion("ZZ")); + // CS is already deprecated so the library doesn't support it. + assertEquals(0, phoneUtil.getCountryCodeForRegion("CS")); } - public void testGetNANPACountries() { - Set nanpaCountries = phoneUtil.getNANPACountries(); - assertEquals(2, nanpaCountries.size()); - assertTrue(nanpaCountries.contains("US")); - assertTrue(nanpaCountries.contains("BS")); + public void testIsNANPACountry() { + assertTrue(phoneUtil.isNANPACountry("US")); + assertTrue(phoneUtil.isNANPACountry("BS")); } public void testIsPossibleNumber() { @@ -857,6 +858,12 @@ public class PhoneNumberUtilTest extends TestCase { assertEquals("", PhoneNumberUtil.extractPossibleNumber("Num-....")); // Leading brackets are stripped - these are not used when parsing. assertEquals("650) 253-0000", PhoneNumberUtil.extractPossibleNumber("(650) 253-0000")); + + // Trailing non-alpha-numeric characters should be removed. + assertEquals("650) 253-0000", PhoneNumberUtil.extractPossibleNumber("(650) 253-0000..- ..")); + assertEquals("650) 253-0000", PhoneNumberUtil.extractPossibleNumber("(650) 253-0000.")); + // This case has a trailing RTL char. + assertEquals("650) 253-0000", PhoneNumberUtil.extractPossibleNumber("(650) 253-0000\u200F")); } public void testMaybeStripNationalPrefix() { @@ -938,7 +945,7 @@ public class PhoneNumberUtilTest extends TestCase { } public void testMaybeExtractCountryCode() { - PhoneMetadata metadata = phoneUtil.getPhoneMetadata("US"); + PhoneMetadata metadata = phoneUtil.getMetadataForRegion("US"); // Note that for the US, the IDD is 011. try { String phoneNumber = "011112-3456789"; @@ -1312,6 +1319,14 @@ public class PhoneNumberUtilTest extends TestCase { assertEquals(usWithExtension, phoneUtil.parse("(800) 901-3355 ext: 7246433", "US")); } + public void testParseAndKeepRaw() throws Exception { + PhoneNumber alphaNumericNumber = + PhoneNumber.newBuilder().setCountryCode(1).setNationalNumber(180074935247L) + .setRawInput("1800 six-flags").build(); + assertEquals(alphaNumericNumber, + phoneUtil.parseAndKeepRawInput("1800 six-flags", "US")); + } + public void testCountryWithNoNumberDesc() { // Andorra is a country where we don't have PhoneNumberDesc info in the meta data. PhoneNumber adNumber = |