Browse Source

IsNumberGeographical public + better detection of "geographical numbers" in geocoder (#1277)

Making function IsNumberGeographical public. This function operates on
the type of number and the country it belongs to only, so may have some
false positives.

Using this in the geocoder so that geocoding now limited to numbers that
we consider geographical, based on their type and country, rather than
just based on their type. The C++ geocoder did not previously check the
number type/country at all.

Indonesian and Chinese mobile numbers have now been added to the list of
possibly-geographical numbers.
pull/1287/head
lararennie 9 years ago
committed by Keghani Kouzoujian
parent
commit
7c84d36ac9
15 changed files with 792 additions and 631 deletions
  1. +12
    -2
      cpp/src/phonenumbers/geocoding/phonenumber_offline_geocoder.cc
  2. +30
    -3
      cpp/src/phonenumbers/phonenumberutil.cc
  3. +14
    -5
      cpp/src/phonenumbers/phonenumberutil.h
  4. +604
    -590
      cpp/src/phonenumbers/test_metadata.cc
  5. +9
    -0
      cpp/test/phonenumbers/geocoding/phonenumber_offline_geocoder_test.cc
  6. +24
    -5
      cpp/test/phonenumbers/phonenumberutil_test.cc
  7. +2
    -13
      java/geocoder/src/com/google/i18n/phonenumbers/geocoding/PhoneNumberOfflineGeocoder.java
  8. +7
    -0
      java/geocoder/test/com/google/i18n/phonenumbers/geocoding/PhoneNumberOfflineGeocoderTest.java
  9. BIN
      java/geocoder/test/com/google/i18n/phonenumbers/geocoding/testing_data/82_en
  10. +39
    -10
      java/libphonenumber/src/com/google/i18n/phonenumbers/PhoneNumberUtil.java
  11. +14
    -1
      java/libphonenumber/test/com/google/i18n/phonenumbers/PhoneNumberUtilTest.java
  12. BIN
      java/libphonenumber/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_CN
  13. +3
    -0
      java/pending_code_changes.txt
  14. +33
    -2
      resources/PhoneNumberMetadataForTesting.xml
  15. +1
    -0
      resources/test/geocoding/en/82.txt

+ 12
- 2
cpp/src/phonenumbers/geocoding/phonenumber_offline_geocoder.cc View File

@ -166,8 +166,13 @@ string PhoneNumberOfflineGeocoder::GetDescriptionForValidNumber(
string PhoneNumberOfflineGeocoder::GetDescriptionForNumber(
const PhoneNumber& number, const Locale& locale) const {
if (!phone_util_->IsValidNumber(number)) {
PhoneNumberUtil::PhoneNumberType number_type =
phone_util_->GetNumberType(number);
if (number_type == PhoneNumberUtil::UNKNOWN) {
return "";
} else if (!phone_util_->IsNumberGeographical(number_type,
number.country_code())) {
return GetCountryNameForNumber(number, locale);
}
return GetDescriptionForValidNumber(number, locale);
}
@ -175,8 +180,13 @@ string PhoneNumberOfflineGeocoder::GetDescriptionForNumber(
string PhoneNumberOfflineGeocoder::GetDescriptionForNumber(
const PhoneNumber& number, const Locale& language,
const string& user_region) const {
if (!phone_util_->IsValidNumber(number)) {
PhoneNumberUtil::PhoneNumberType number_type =
phone_util_->GetNumberType(number);
if (number_type == PhoneNumberUtil::UNKNOWN) {
return "";
} else if (!phone_util_->IsNumberGeographical(number_type,
number.country_code())) {
return GetCountryNameForNumber(number, language);
}
return GetDescriptionForValidNumber(number, language, user_region);
}


+ 30
- 3
cpp/src/phonenumbers/phonenumberutil.cc View File

@ -386,9 +386,15 @@ class PhoneNumberRegExpsAndMappings {
mobile_token_mappings_.insert(std::make_pair(52, '1'));
mobile_token_mappings_.insert(std::make_pair(54, '9'));
geo_mobile_countries_without_mobile_area_codes_.insert(86); // China
geo_mobile_countries_.insert(52); // Mexico
geo_mobile_countries_.insert(54); // Argentina
geo_mobile_countries_.insert(55); // Brazil
// Indonesia: some prefixes only (fixed CMDA wireless)
geo_mobile_countries_.insert(62);
geo_mobile_countries_.insert(
geo_mobile_countries_without_mobile_area_codes_.begin(),
geo_mobile_countries_without_mobile_area_codes_.end());
}
// Small string helpers since StrCat has a maximum number of arguments. These
@ -448,6 +454,13 @@ class PhoneNumberRegExpsAndMappings {
// the length of the mobile token.
map<int, char> mobile_token_mappings_;
// Set of country codes that have geographically assigned mobile numbers (see
// geo_mobile_countries_ below) which are not based on *area codes*. For
// example, in China mobile numbers start with a carrier indicator, and beyond
// that are geographically assigned: this carrier indicator is not considered
// to be an area code.
set<int> geo_mobile_countries_without_mobile_area_codes_;
// Set of country calling codes that have geographically assigned mobile
// numbers. This may not be complete; we add calling codes case by case, as we
// find geographical mobile numbers or hear from user reports.
@ -538,6 +551,7 @@ class PhoneNumberRegExpsAndMappings {
alpha_phone_mappings_(),
all_plus_number_grouping_symbols_(),
mobile_token_mappings_(),
geo_mobile_countries_without_mobile_area_codes_(),
geo_mobile_countries_(),
unique_international_prefix_(regexp_factory_->CreateRegExp(
/* "[\\d]+(?:[~⁓∼~][\\d]+)?" */
@ -2148,11 +2162,15 @@ bool PhoneNumberUtil::IsValidNumberForRegion(const PhoneNumber& number,
bool PhoneNumberUtil::IsNumberGeographical(
const PhoneNumber& phone_number) const {
PhoneNumberType number_type = GetNumberType(phone_number);
return IsNumberGeographical(GetNumberType(phone_number),
phone_number.country_code());
}
bool PhoneNumberUtil::IsNumberGeographical(
PhoneNumberType number_type, int country_calling_code) const {
return number_type == PhoneNumberUtil::FIXED_LINE ||
number_type == PhoneNumberUtil::FIXED_LINE_OR_MOBILE ||
(reg_exps_->geo_mobile_countries_.find(phone_number.country_code())
(reg_exps_->geo_mobile_countries_.find(country_calling_code)
!= reg_exps_->geo_mobile_countries_.end() &&
number_type == PhoneNumberUtil::MOBILE);
}
@ -2293,7 +2311,16 @@ int PhoneNumberUtil::GetLengthOfGeographicalAreaCode(
return 0;
}
if (!IsNumberGeographical(number)) {
PhoneNumberType type = GetNumberType(number);
int country_calling_code = number.country_code();
if (type == PhoneNumberUtil::MOBILE &&
reg_exps_->geo_mobile_countries_without_mobile_area_codes_.find(
country_calling_code) !=
reg_exps_->geo_mobile_countries_without_mobile_area_codes_.end()) {
return 0;
}
if (!IsNumberGeographical(type, country_calling_code)) {
return 0;
}


+ 14
- 5
cpp/src/phonenumbers/phonenumberutil.h View File

@ -489,6 +489,20 @@ class PhoneNumberUtil : public Singleton<PhoneNumberUtil> {
const string& number,
const string& region_dialing_from) const;
// Tests whether a phone number has a geographical association. It checks if
// the number is associated to a certain region in the country where it
// belongs to. Note that this doesn't verify if the number is actually in use.
bool IsNumberGeographical(const PhoneNumber& phone_number) const;
// Tests whether a phone number has a geographical association, as represented
// by its type and the country it belongs to.
//
// This version of IsNumberGeographical exists since calculating the phone
// number type is expensive; if we have already done this, we don't want to do
// it again.
bool IsNumberGeographical(PhoneNumberType phone_number_type,
int country_calling_code) const;
// Gets a valid fixed-line number for the specified region. Returns false if
// the region was unknown, or the region 001 is passed in. For 001
// (representing non-geographical numbers), call
@ -719,11 +733,6 @@ class PhoneNumberUtil : public Singleton<PhoneNumberUtil> {
// Trims unwanted end characters from a phone number string.
void TrimUnwantedEndChars(string* number) const;
// Tests whether a phone number has a geographical association. It checks if
// the number is associated to a certain region in the country where it
// belongs to. Note that this doesn't verify if the number is actually in use.
bool IsNumberGeographical(const PhoneNumber& phone_number) const;
// Helper function to check region code is not unknown or null.
bool IsValidRegionCode(const string& region_code) const;


+ 604
- 590
cpp/src/phonenumbers/test_metadata.cc
File diff suppressed because it is too large
View File


+ 9
- 0
cpp/test/phonenumbers/geocoding/phonenumber_offline_geocoder_test.cc View File

@ -53,6 +53,7 @@ class PhoneNumberOfflineGeocoderTest : public testing::Test {
KO_NUMBER2(MakeNumber(82, 322123456UL)),
KO_NUMBER3(MakeNumber(82, 6421234567ULL)),
KO_INVALID_NUMBER(MakeNumber(82, 1234UL)),
KO_MOBILE(MakeNumber(82, 101234567ULL)),
US_NUMBER1(MakeNumber(1, 6502530000ULL)),
US_NUMBER2(MakeNumber(1, 6509600000ULL)),
US_NUMBER3(MakeNumber(1, 2128120000UL)),
@ -82,6 +83,7 @@ class PhoneNumberOfflineGeocoderTest : public testing::Test {
const PhoneNumber KO_NUMBER2;
const PhoneNumber KO_NUMBER3;
const PhoneNumber KO_INVALID_NUMBER;
const PhoneNumber KO_MOBILE;
const PhoneNumber US_NUMBER1;
const PhoneNumber US_NUMBER2;
@ -201,5 +203,12 @@ TEST_F(PhoneNumberOfflineGeocoderTest, TestGetDescriptionForInvalidNumber) {
kEnglishLocale));
}
TEST_F(PhoneNumberOfflineGeocoderTest,
TestGetDescriptionForNonGeographicalNumberWithGeocodingPrefix) {
// We have a geocoding prefix, but we shouldn't use it since this is not
// geographical.
EXPECT_EQ("South Korea",
geocoder_->GetDescriptionForNumber(KO_MOBILE, kEnglishLocale));
}
} // namespace phonenumbers
} // namespace i18n

+ 24
- 5
cpp/test/phonenumbers/phonenumberutil_test.cc View File

@ -1165,7 +1165,7 @@ TEST_F(PhoneNumberUtilTest, FormatNumberForMobileDialing) {
// numbers are always output in international format, but short numbers are
// in national format.
test_number.set_country_code(1);
test_number.set_national_number(6502530000LL);
test_number.set_national_number(6502530000L);
phone_util_.FormatNumberForMobileDialing(
test_number, RegionCode::US(), false, &formatted_number);
EXPECT_EQ("+16502530000", formatted_number);
@ -1341,9 +1341,10 @@ TEST_F(PhoneNumberUtilTest, GetLengthOfGeographicalAreaCode) {
number.set_national_number(2070313000ULL);
EXPECT_EQ(2, phone_util_.GetLengthOfGeographicalAreaCode(number));
// A UK mobile phone, which has no area code.
// A mobile number in the UK does not have an area code (by default, mobile
// numbers do not, unless they have been added to our list of exceptions).
number.set_country_code(44);
number.set_national_number(7123456789ULL);
number.set_national_number(7912345678ULL);
EXPECT_EQ(0, phone_util_.GetLengthOfGeographicalAreaCode(number));
// Google Buenos Aires, which has area code "11".
@ -1351,6 +1352,11 @@ TEST_F(PhoneNumberUtilTest, GetLengthOfGeographicalAreaCode) {
number.set_national_number(1155303000ULL);
EXPECT_EQ(2, phone_util_.GetLengthOfGeographicalAreaCode(number));
// A mobile number in Argentina also has an area code.
number.set_country_code(54);
number.set_national_number(91187654321);
EXPECT_EQ(3, phone_util_.GetLengthOfGeographicalAreaCode(number));
// Google Sydney, which has area code "2".
number.set_country_code(61);
number.set_national_number(293744000ULL);
@ -1373,6 +1379,12 @@ TEST_F(PhoneNumberUtilTest, GetLengthOfGeographicalAreaCode) {
number.set_country_code(800);
number.set_national_number(12345678ULL);
EXPECT_EQ(0, phone_util_.GetLengthOfGeographicalAreaCode(number));
// A mobile number from China is geographical, but does not have an area code.
PhoneNumber cn_mobile;
cn_mobile.set_country_code(86);
cn_mobile.set_national_number(18912341234ULL);
EXPECT_EQ(0, phone_util_.GetLengthOfGeographicalAreaCode(cn_mobile));
}
TEST_F(PhoneNumberUtilTest, GetLengthOfNationalDestinationCode) {
@ -1392,9 +1404,9 @@ TEST_F(PhoneNumberUtilTest, GetLengthOfNationalDestinationCode) {
number.set_national_number(2070313000ULL);
EXPECT_EQ(2, phone_util_.GetLengthOfNationalDestinationCode(number));
// A UK mobile phone, which has NDC "7123"
// A UK mobile phone, which has NDC "7912"
number.set_country_code(44);
number.set_national_number(7123456789ULL);
number.set_national_number(7912345678ULL);
EXPECT_EQ(4, phone_util_.GetLengthOfNationalDestinationCode(number));
// Google Buenos Aires, which has NDC "11".
@ -1444,6 +1456,13 @@ TEST_F(PhoneNumberUtilTest, GetLengthOfNationalDestinationCode) {
number.set_country_code(800);
number.set_national_number(12345678ULL);
EXPECT_EQ(4, phone_util_.GetLengthOfNationalDestinationCode(number));
// A mobile number from China is geographical, but does not have an area code:
// however it still can be considered to have a national destination code.
PhoneNumber cn_mobile;
cn_mobile.set_country_code(86);
cn_mobile.set_national_number(18912341234ULL);
EXPECT_EQ(3, phone_util_.GetLengthOfNationalDestinationCode(cn_mobile));
}
TEST_F(PhoneNumberUtilTest, GetCountryMobileToken) {


+ 2
- 13
java/geocoder/src/com/google/i18n/phonenumbers/geocoding/PhoneNumberOfflineGeocoder.java View File

@ -186,7 +186,7 @@ public class PhoneNumberOfflineGeocoder {
PhoneNumberType numberType = phoneUtil.getNumberType(number);
if (numberType == PhoneNumberType.UNKNOWN) {
return "";
} else if (!canBeGeocoded(numberType)) {
} else if (!phoneUtil.isNumberGeographical(numberType, number.getCountryCode())) {
return getCountryNameForNumber(number, languageCode);
}
return getDescriptionForValidNumber(number, languageCode);
@ -209,20 +209,9 @@ public class PhoneNumberOfflineGeocoder {
PhoneNumberType numberType = phoneUtil.getNumberType(number);
if (numberType == PhoneNumberType.UNKNOWN) {
return "";
} else if (!canBeGeocoded(numberType)) {
} else if (!phoneUtil.isNumberGeographical(numberType, number.getCountryCode())) {
return getCountryNameForNumber(number, languageCode);
}
return getDescriptionForValidNumber(number, languageCode, userRegion);
}
/**
* A similar method is implemented as PhoneNumberUtil.isNumberGeographical, which performs a
* stricter check, as it determines if a number has a geographical association. Also, if new
* phone number types were added, we should check if this other method should be updated too.
*/
private boolean canBeGeocoded(PhoneNumberType numberType) {
return (numberType == PhoneNumberType.FIXED_LINE ||
numberType == PhoneNumberType.MOBILE ||
numberType == PhoneNumberType.FIXED_LINE_OR_MOBILE);
}
}

+ 7
- 0
java/geocoder/test/com/google/i18n/phonenumbers/geocoding/PhoneNumberOfflineGeocoderTest.java View File

@ -41,6 +41,8 @@ public class PhoneNumberOfflineGeocoderTest extends TestCase {
new PhoneNumber().setCountryCode(82).setNationalNumber(6421234567L);
private static final PhoneNumber KO_INVALID_NUMBER =
new PhoneNumber().setCountryCode(82).setNationalNumber(1234L);
private static final PhoneNumber KO_MOBILE =
new PhoneNumber().setCountryCode(82).setNationalNumber(101234567L);
private static final PhoneNumber US_NUMBER1 =
new PhoneNumber().setCountryCode(1).setNationalNumber(6502530000L);
private static final PhoneNumber US_NUMBER2 =
@ -160,4 +162,9 @@ public class PhoneNumberOfflineGeocoderTest extends TestCase {
assertEquals("", geocoder.getDescriptionForNumber(KO_INVALID_NUMBER, Locale.ENGLISH));
assertEquals("", geocoder.getDescriptionForNumber(US_INVALID_NUMBER, Locale.ENGLISH));
}
public void testGetDescriptionForNonGeographicalNumberWithGeocodingPrefix() {
// We have a geocoding prefix, but we shouldn't use it since this is not geographical.
assertEquals("South Korea", geocoder.getDescriptionForNumber(KO_MOBILE, Locale.ENGLISH));
}
}

BIN
java/geocoder/test/com/google/i18n/phonenumbers/geocoding/testing_data/82_en View File


+ 39
- 10
java/libphonenumber/src/com/google/i18n/phonenumbers/PhoneNumberUtil.java View File

@ -88,9 +88,17 @@ public class PhoneNumberUtil {
// be the length of the area code plus the length of the mobile token.
private static final Map<Integer, String> MOBILE_TOKEN_MAPPINGS;
// Set of country codes that have geographically assigned mobile numbers (see GEO_MOBILE_COUNTRIES
// below) which are not based on *area codes*. For example, in China mobile numbers start with a
// carrier indicator, and beyond that are geographically assigned: this carrier indicator is not
// considered to be an area code.
private static final Set<Integer> GEO_MOBILE_COUNTRIES_WITHOUT_MOBILE_AREA_CODES;
// Set of country calling codes that have geographically assigned mobile numbers. This may not be
// complete; we add calling codes case by case, as we find geographical mobile numbers or hear
// from user reports.
// from user reports. Note that countries like the US, where we can't distinguish between
// fixed-line or mobile numbers, are not listed here, since we consider FIXED_LINE_OR_MOBILE to be
// a possibly geographically-related type anyway (like FIXED_LINE).
private static final Set<Integer> GEO_MOBILE_COUNTRIES;
// The PLUS_SIGN signifies the international prefix.
@ -124,10 +132,17 @@ public class PhoneNumberUtil {
mobileTokenMap.put(54, "9");
MOBILE_TOKEN_MAPPINGS = Collections.unmodifiableMap(mobileTokenMap);
HashSet<Integer> geoMobileCountriesWithoutMobileAreaCodes = new HashSet<Integer>();
geoMobileCountriesWithoutMobileAreaCodes.add(86); // China
GEO_MOBILE_COUNTRIES_WITHOUT_MOBILE_AREA_CODES =
Collections.unmodifiableSet(geoMobileCountriesWithoutMobileAreaCodes);
HashSet<Integer> geoMobileCountries = new HashSet<Integer>();
geoMobileCountries.add(52); // Mexico
geoMobileCountries.add(54); // Argentina
geoMobileCountries.add(55); // Brazil
geoMobileCountries.add(62); // Indonesia: some prefixes only (fixed CMDA wireless)
geoMobileCountries.addAll(geoMobileCountriesWithoutMobileAreaCodes);
GEO_MOBILE_COUNTRIES = Collections.unmodifiableSet(geoMobileCountries);
// Simple ASCII digits map used to populate ALPHA_PHONE_MAPPINGS and
@ -802,7 +817,17 @@ public class PhoneNumberUtil {
return 0;
}
if (!isNumberGeographical(number)) {
PhoneNumberType type = getNumberType(number);
int countryCallingCode = number.getCountryCode();
if (type == PhoneNumberType.MOBILE
// Note this is a rough heuristic; it doesn't cover Indonesia well, for example, where area
// codes are present for some mobile phones but not for others. We have no better way of
// representing this in the metadata at this point.
&& GEO_MOBILE_COUNTRIES_WITHOUT_MOBILE_AREA_CODES.contains(countryCallingCode)) {
return 0;
}
if (!isNumberGeographical(type, countryCallingCode)) {
return 0;
}
@ -1017,18 +1042,22 @@ public class PhoneNumberUtil {
* Tests whether a phone number has a geographical association. It checks if the number is
* associated to a certain region in the country where it belongs to. Note that this doesn't
* verify if the number is actually in use.
*
* A similar method is implemented as PhoneNumberOfflineGeocoder.canBeGeocoded, which performs a
* looser check, since it only prevents cases where prefixes overlap for geocodable and
* non-geocodable numbers. Also, if new phone number types were added, we should check if this
* other method should be updated too.
*/
boolean isNumberGeographical(PhoneNumber phoneNumber) {
PhoneNumberType numberType = getNumberType(phoneNumber);
public boolean isNumberGeographical(PhoneNumber phoneNumber) {
return isNumberGeographical(getNumberType(phoneNumber), phoneNumber.getCountryCode());
}
/**
* Tests whether a phone number has a geographical association, as represented by its type and the
* country it belongs to.
*
* This version of isNumberGeographical exists since calculating the phone number type is
* expensive; if we have already done this, we don't want to do it again.
*/
public boolean isNumberGeographical(PhoneNumberType numberType, int countryCallingCode) {
return numberType == PhoneNumberType.FIXED_LINE
|| numberType == PhoneNumberType.FIXED_LINE_OR_MOBILE
|| (GEO_MOBILE_COUNTRIES.contains(phoneNumber.getCountryCode())
|| (GEO_MOBILE_COUNTRIES.contains(countryCallingCode)
&& numberType == PhoneNumberType.MOBILE);
}


+ 14
- 1
java/libphonenumber/test/com/google/i18n/phonenumbers/PhoneNumberUtilTest.java View File

@ -235,12 +235,16 @@ public class PhoneNumberUtilTest extends TestMetadataTestCase {
// Google London, which has area code "20".
assertEquals(2, phoneUtil.getLengthOfGeographicalAreaCode(GB_NUMBER));
// A UK mobile phone, which has no area code.
// A mobile number in the UK does not have an area code (by default, mobile numbers do not,
// unless they have been added to our list of exceptions).
assertEquals(0, phoneUtil.getLengthOfGeographicalAreaCode(GB_MOBILE));
// Google Buenos Aires, which has area code "11".
assertEquals(2, phoneUtil.getLengthOfGeographicalAreaCode(AR_NUMBER));
// A mobile number in Argentina also has an area code.
assertEquals(3, phoneUtil.getLengthOfGeographicalAreaCode(AR_MOBILE));
// Google Sydney, which has area code "2".
assertEquals(1, phoneUtil.getLengthOfGeographicalAreaCode(AU_NUMBER));
@ -255,6 +259,10 @@ public class PhoneNumberUtilTest extends TestMetadataTestCase {
// An international toll free number, which has no area code.
assertEquals(0, phoneUtil.getLengthOfGeographicalAreaCode(INTERNATIONAL_TOLL_FREE));
// A mobile number from China is geographical, but does not have an area code.
PhoneNumber cnMobile = new PhoneNumber().setCountryCode(86).setNationalNumber(18912341234L);
assertEquals(0, phoneUtil.getLengthOfGeographicalAreaCode(cnMobile));
}
public void testGetLengthOfNationalDestinationCode() {
@ -291,6 +299,11 @@ public class PhoneNumberUtilTest extends TestMetadataTestCase {
// An international toll free number, which has NDC "1234".
assertEquals(4, phoneUtil.getLengthOfNationalDestinationCode(INTERNATIONAL_TOLL_FREE));
// A mobile number from China is geographical, but does not have an area code: however it still
// can be considered to have a national destination code.
PhoneNumber cnMobile = new PhoneNumber().setCountryCode(86).setNationalNumber(18912341234L);
assertEquals(3, phoneUtil.getLengthOfNationalDestinationCode(cnMobile));
}
public void testGetCountryMobileToken() {


BIN
java/libphonenumber/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_CN View File


+ 3
- 0
java/pending_code_changes.txt View File

@ -1,5 +1,8 @@
- Deleted unsupported SingleFilePhoneNumberMetadataProto.
Code changes:
- Refactored metadata loading and closed all streams after loading.
- Made isNumberGeographical public, and changed the geocoder to
use this when checking whether to give a detailed answer or country-level
only.
Build changes:
- Use protobuf-javanano 3.0.0-alpha-7 from Maven Central.

+ 33
- 2
resources/PhoneNumberMetadataForTesting.xml View File

@ -236,8 +236,9 @@
</territory>
<!-- China -->
<!-- Used to test as-you-type-formatter with complicated number format patterns. -->
<territory id="CN" countryCode="86">
<!-- Used to test as-you-type-formatter with complicated number format patterns. Also used to
test that not all geographical mobile numbers have an area code. -->
<territory id="CN" countryCode="86" nationalPrefix="0">
<availableFormats>
<numberFormat nationalPrefixFormattingRule="$NP$FG" pattern="(\d{3})(\d{5,6})"
carrierCodeFormattingRule="$CC $FG">
@ -251,7 +252,37 @@
</leadingDigits>
<format>$1 $2</format>
</numberFormat>
<!-- Note that mobile numbers do not get formatted with the national prefix. -->
<numberFormat nationalPrefixFormattingRule="$FG" pattern="(\d{3})(\d{8})">
<leadingDigits>1</leadingDigits>
<format>$1 $2</format>
</numberFormat>
</availableFormats>
<generalDesc>
<nationalNumberPattern>
[1-7]\d{6,11}|
8[0-357-9]\d{6,9}|
9\d{7,10}
</nationalNumberPattern>
<possibleNumberPattern>\d{4,12}</possibleNumberPattern>
</generalDesc>
<fixedLine>
<nationalNumberPattern>[2-9]\d{10}</nationalNumberPattern>
<possibleNumberPattern>\d{11}</possibleNumberPattern>
<exampleNumber>91234567</exampleNumber>
</fixedLine>
<mobile>
<nationalNumberPattern>
1(?:
[38]\d|
4[57]|
5[0-35-9]|
7[0136-8]
)\d{8}
</nationalNumberPattern>
<possibleNumberPattern>\d{11}</possibleNumberPattern>
<exampleNumber>13123456789</exampleNumber>
</mobile>
</territory>
<!-- Christmas Islands -->


+ 1
- 0
resources/test/geocoding/en/82.txt View File

@ -12,6 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
8210|Mobile prefix, should not be geocoded.
822|Seoul
8231|Gyeonggi
8232|Incheon


Loading…
Cancel
Save