private bool matchesEmergencyNumberHelper(String number, String regionCode, bool allowPrefixMatch) { number = PhoneNumberUtil.extractPossibleNumber(number); if (PhoneNumberUtil.PLUS_CHARS_PATTERN.MatchBeginning(number).Success) { // Returns false if the number starts with a plus sign. We don't believe dialing the country // code before emergency numbers (e.g. +1911) works, but later, if that proves to work, we can // add additional logic here to handle it. return(false); } PhoneMetadata metadata = MetadataManager.getShortNumberMetadataForRegion(regionCode); if (metadata == null || !metadata.HasEmergency()) { return(false); } var emergencyNumberPattern = new JavaRegex(metadata.getEmergency().getNationalNumberPattern()); String normalizedNumber = PhoneNumberUtil.normalizeDigitsOnly(number); return((!allowPrefixMatch || REGIONS_WHERE_EMERGENCY_NUMBERS_MUST_BE_EXACT.Contains(regionCode)) ? emergencyNumberPattern.MatchWhole(normalizedNumber).Success : emergencyNumberPattern.MatchBeginning(normalizedNumber).Success); }
private bool isFormatEligible(String format) { return(ELIGIBLE_FORMAT_PATTERN.MatchWhole(format).Success); }
/** * 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.MatchWhole(candidate).Success || PUB_PAGES.Match(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.CompareTo(PhoneNumberUtil.Leniency.VALID) >= 0) { // 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); // Check Israel * numbers: these are a special case in that they are four-digit numbers that // our library supports, but they can only be dialled with a leading *. Since we don't // actually store or detect the * in our phone number library, this means in practice we // detect most four digit numbers as being valid for Israel. We are considering moving these // numbers to ShortNumberInfo instead, in which case this problem would go away, but in the // meantime we want to restrict the false matches so we only allow these numbers if they are // preceded by a star. We enforce this for all leniency levels even though these numbers are // technically accepted by isPossibleNumber and isValidNumber since we consider it to be a // deficiency in those methods that they accept these numbers without the *. // TODO: Remove this or make it significantly less hacky once we've decided how to // handle these short codes going forward in ShortNumberInfo. We could use the formatting // rules for instance, but that would be slower. if (phoneUtil.getRegionCodeForCountryCode(number.getCountryCode()).Equals("IL") && phoneUtil.getNationalSignificantNumber(number).Length == 4 && (offset == 0 || (offset > 0 && text[offset - 1] != '*'))) { // No match. return(null); } if (leniency.verify(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. number.clearCountryCodeSource(); number.clearRawInput(); number.clearPreferredDomesticCarrierCode(); return(new PhoneNumberMatch(offset, candidate, number)); } } catch (NumberParseException) { // ignore and continue } return(null); }