Beispiel #1
0
        /// <summary>
        /// Parses a phone number from the {@code candidate} using {@link PhoneNumberUtil#parse} and
        /// verifies it matches the requested {@link #leniency}. If parsing and verification succeed, a
        /// corresponding <see cref="PhoneNumberMatch" /> is returned, otherwise this method returns null.
        /// </summary>
        ///
        /// <param name="candidate">the candidate match</param>
        /// <param name="offset">the offset of <c>candidate</c> within <see cref="text" /></param>
        /// <returns>the parsed and validated phone number match, or null</returns>
        private PhoneNumberMatch ParseAndVerify(string candidate, int offset)
        {
            try
            {
                // Check the candidate doesn't contain any formatting which would indicate that it really
                // isn't a phone number.
                if (!MatchingBrackets.IsMatchAll(candidate))
                {
                    return(null);
                }

                // If leniency is set to VALID or stricter, we also want to skip numbers that are surrounded
                // by Latin alphabetic characters, to skip cases like abc8005001234 or 8005001234def.
                if (leniency >= PhoneNumberUtil.Leniency.VALID)
                {
                    // If the candidate is not at the start of the text, and does not start with phone-number
                    // punctuation, check the previous character.
                    if (offset > 0 && !LeadClass.IsMatchBeginning(candidate))
                    {
                        var previousChar = text[offset - 1];
                        // We return null if it is a latin letter or an invalid punctuation symbol.
                        if (IsInvalidPunctuationSymbol(previousChar) || IsLatinLetter(previousChar))
                        {
                            return(null);
                        }
                    }
                    var lastCharIndex = offset + candidate.Length;
                    if (lastCharIndex < text.Length)
                    {
                        var nextChar = text[lastCharIndex];
                        if (IsInvalidPunctuationSymbol(nextChar) || IsLatinLetter(nextChar))
                        {
                            return(null);
                        }
                    }
                }

                var number = phoneUtil.ParseAndKeepRawInput(candidate, preferredRegion);
                if (leniency.Verify(number, candidate, phoneUtil, this))
                {
                    // We used parseAndKeepRawInput to create this number, but for now we don't return the extra
                    // values parsed. TODO: stop clearing all values here and switch all users over
                    // to using rawInput() rather than the rawString() of PhoneNumberMatch.
                    var bnumber = number.ToBuilder();
                    bnumber.ClearCountryCodeSource();
                    bnumber.ClearRawInput();
                    bnumber.ClearPreferredDomesticCarrierCode();
                    return(new PhoneNumberMatch(offset, candidate, bnumber.Build()));
                }
            }
            catch (NumberParseException)
            {
                // ignore and continue
            }
            return(null);
        }
        private void GetAvailableFormats(string leadingDigits)
        {
            // First decide whether we should use international or national number rules.
            var isInternationalNumber = isCompleteNumber && extractedNationalPrefix.Length == 0;
            var formatList            =
                isInternationalNumber && currentMetadata.IntlNumberFormatCount > 0
                    ? currentMetadata.IntlNumberFormatList
                    : currentMetadata.NumberFormatList;

            foreach (var format in formatList)
            {
                // Discard a few formats that we know are not relevant based on the presence of the national
                // prefix.
                if (extractedNationalPrefix.Length > 0 &&
                    PhoneNumberUtil.FormattingRuleHasFirstGroupOnly(
                        format.NationalPrefixFormattingRule) &&
                    !format.NationalPrefixOptionalWhenFormatting &&
                    !format.HasDomesticCarrierCodeFormattingRule)
                {
                    // If it is a national number that had a national prefix, any rules that aren't valid with a
                    // national prefix should be excluded. A rule that has a carrier-code formatting rule is
                    // kept since the national prefix might actually be an extracted carrier code - we don't
                    // distinguish between these when extracting it in the AYTF.
                    continue;
                }
                else if (extractedNationalPrefix.Length == 0 &&
                         !isCompleteNumber &&
                         !PhoneNumberUtil.FormattingRuleHasFirstGroupOnly(
                             format.NationalPrefixFormattingRule) &&
                         !format.NationalPrefixOptionalWhenFormatting)
                {
                    // This number was entered without a national prefix, and this formatting rule requires one,
                    // so we discard it.
                    continue;
                }
                if (EligibleFormatPattern.IsMatchAll(format.Format))
                {
                    possibleFormats.Add(format);
                }
            }
            NarrowDownPossibleFormats(leadingDigits);
        }