/**
* 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 {@link PhoneNumberMatch} is returned, otherwise this method returns null.
*
* @param candidate the candidate match
* @param offset the offset of {@code candidate} within {@link #text}
* @return the parsed and validated phone number match, or null
*/
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 (!MATCHING_BRACKETS.MatchAll(candidate).Success)
{
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 && !LEAD_CLASS.MatchBeginning(candidate).Success)
{
char 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);
}
}
int lastCharIndex = offset + candidate.Length;
if (lastCharIndex < text.Length)
{
char nextChar = text[lastCharIndex];
if (IsInvalidPunctuationSymbol(nextChar) || IsLatinLetter(nextChar))
{
return(null);
}
}
}
PhoneNumber number = phoneUtil.ParseAndKeepRawInput(candidate, preferredRegion);
if (phoneUtil.Verify(leniency, number, candidate, phoneUtil))
{
// 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);
}