public GetNationalSignificantNumber ( |
||
number | ||
return | String |
internal static bool IsNationalPrefixPresentIfRequired( PhoneNumber number, PhoneNumberUtil util) { // First, check how we deduced the country code. If it was written in international format, // then the national prefix is not required. if (number.CountryCodeSource != CountryCodeSource.FROM_DEFAULT_COUNTRY) { return true; } String phoneNumberRegion = util.GetRegionCodeForCountryCode(number.CountryCode); PhoneMetadata metadata = util.GetMetadataForRegion(phoneNumberRegion); if (metadata == null) { return true; } // Check if a national prefix should be present when formatting this number. String nationalNumber = util.GetNationalSignificantNumber(number); NumberFormat formatRule = util.ChooseFormattingPatternForNumber(metadata.NumberFormatList, nationalNumber); // To do this, we check that a national prefix formatting rule was present and that it wasn't // just the first-group symbol ($1) with punctuation. if ((formatRule != null) && formatRule.NationalPrefixFormattingRule.Length > 0) { if (formatRule.NationalPrefixOptionalWhenFormatting) { // The national-prefix is optional in these cases, so we don't need to check if it was // present. return true; } // Remove the first-group symbol. String candidateNationalPrefixRule = formatRule.NationalPrefixFormattingRule; // We assume that the first-group symbol will never be _before_ the national prefix. candidateNationalPrefixRule = candidateNationalPrefixRule.Substring(0, candidateNationalPrefixRule.IndexOf("${1}")); candidateNationalPrefixRule = PhoneNumberUtil.NormalizeDigitsOnly(candidateNationalPrefixRule); if (candidateNationalPrefixRule.Length == 0) { // National Prefix not needed for this number. return true; } // Normalize the remainder. String rawInputCopy = PhoneNumberUtil.NormalizeDigitsOnly(number.RawInput); StringBuilder rawInput = new StringBuilder(rawInputCopy); // Check if we found a national prefix and/or carrier code at the start of the raw input, // and return the result. return util.MaybeStripNationalPrefixAndCarrierCode(rawInput, metadata, null); } return true; }
public bool Verify(Leniency leniency, PhoneNumber number, String candidate, PhoneNumberUtil util) { switch (leniency) { case Leniency.POSSIBLE: return IsPossibleNumber(number); case Leniency.VALID: { if (!util.IsValidNumber(number) || !PhoneNumberUtil.ContainsOnlyValidXChars(number, candidate, util)) return false; return PhoneNumberUtil.IsNationalPrefixPresentIfRequired(number, util); } case Leniency.STRICT_GROUPING: { if (!util.IsValidNumber(number) || !PhoneNumberUtil.ContainsOnlyValidXChars(number, candidate, util) || PhoneNumberUtil.ContainsMoreThanOneSlash(candidate) || !PhoneNumberUtil.IsNationalPrefixPresentIfRequired(number, util)) { return false; } // TODO: Evaluate how this works for other locales (testing has been // limited to NANPA regions) and optimise if necessary. String[] formattedNumberGroups = PhoneNumberUtil.GetNationalNumberGroups(util, number); StringBuilder normalizedCandidate = PhoneNumberUtil.NormalizeDigits(candidate, true /* keep strip non-digits */); int fromIndex = 0; // Check each group of consecutive digits are not broken into separate groups in the // {@code candidate} string. for (int i = 0; i < formattedNumberGroups.Length; i++) { // Fails if the substring of {@code candidate} starting from {@code fromIndex} doesn't // contain the consecutive digits in formattedNumberGroups[i]. fromIndex = normalizedCandidate.ToString().IndexOf(formattedNumberGroups[i], fromIndex); if (fromIndex < 0) { return false; } // Moves {@code fromIndex} forward. fromIndex += formattedNumberGroups[i].Length; if (i == 0 && fromIndex < normalizedCandidate.Length) { // We are at the position right after the NDC. if (char.IsDigit(normalizedCandidate[fromIndex])) { // This means there is no formatting symbol after the NDC. In this case, we only // accept the number if there is no formatting symbol at all in the number, except // for extensions. String nationalSignificantNumber = util.GetNationalSignificantNumber(number); return normalizedCandidate.ToString().Substring(fromIndex - formattedNumberGroups[i].Length) .StartsWith(nationalSignificantNumber); } } } // The check here makes sure that we haven't mistakenly already used the extension to // match the last group of the subscriber number. Note the extension cannot have // formatting in-between digits. return normalizedCandidate.ToString().Substring(fromIndex).Contains(number.Extension); } case Leniency.EXACT_GROUPING: default: { if (!util.IsValidNumber(number) || !ContainsOnlyValidXChars(number, candidate, util) || ContainsMoreThanOneSlash(candidate) || !IsNationalPrefixPresentIfRequired(number, util)) { return false; } // TODO: Evaluate how this works for other locales (testing has been // limited to NANPA regions) and optimise if necessary. StringBuilder normalizedCandidate = PhoneNumberUtil.NormalizeDigits(candidate, true /* keep strip non-digits */); String[] candidateGroups = NON_DIGITS_PATTERN.Split(normalizedCandidate.ToString()); // Set this to the last group, skipping it if the number has an extension. int candidateNumberGroupIndex = number.HasExtension ? candidateGroups.Length - 2 : candidateGroups.Length - 1; // First we check if the national significant number is formatted as a block. // We use contains and not equals, since the national significant number may be present with // a prefix such as a national number prefix, or the country code itself. if (candidateGroups.Length == 1 || candidateGroups[candidateNumberGroupIndex].Contains( util.GetNationalSignificantNumber(number))) { return true; } String[] formattedNumberGroups = PhoneNumberUtil.GetNationalNumberGroups(util, number); // Starting from the end, go through in reverse, excluding the first group, and check the // candidate and number groups are the same. for (int formattedNumberGroupIndex = (formattedNumberGroups.Length - 1); formattedNumberGroupIndex > 0 && candidateNumberGroupIndex >= 0; formattedNumberGroupIndex--, candidateNumberGroupIndex--) { if (!candidateGroups[candidateNumberGroupIndex].Equals( formattedNumberGroups[formattedNumberGroupIndex])) { return false; } } // Now check the first group. There may be a national prefix at the start, so we only check // that the candidate group ends with the formatted number group. return (candidateNumberGroupIndex >= 0 && candidateGroups[candidateNumberGroupIndex].EndsWith(formattedNumberGroups[0])); } } }