summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShaopeng Jia <shaopengjia@google.com>2010-03-23 18:29:45 +0100
committerShaopeng Jia <shaopengjia@google.com>2010-03-25 11:11:08 +0100
commit7900ea273b8c33b3c6f70d7dd559127938d0fc3d (patch)
treef10b150190949c7c81de1084deb9f33d3c04d726
parent1524ca8c53cd2c3adee0bb2e2b95a93fee976862 (diff)
downloadlibphonenumber-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.android2
-rw-r--r--java/resources/com/google/i18n/phonenumbers/src/PhoneNumberMetaData.xml856
-rwxr-xr-x[-rw-r--r--]java/resources/com/google/i18n/phonenumbers/src/generated_files/PhoneNumberMetadataProtobin71645 -> 79839 bytes
-rw-r--r--java/src/com/google/i18n/phonenumbers/AsYouTypeFormatter.java15
-rw-r--r--java/src/com/google/i18n/phonenumbers/PhoneNumberUtil.java208
-rw-r--r--java/src/com/google/i18n/phonenumbers/Phonenumber.java42
-rw-r--r--java/src/com/google/i18n/phonenumbers/phonenumber.proto5
-rw-r--r--java/test/com/google/i18n/phonenumbers/AsYouTypeFormatterTest.java53
-rw-r--r--java/test/com/google/i18n/phonenumbers/PhoneNumberUtilTest.java35
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
index 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
Binary files differ
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 =