internal static boolean allNumberGroupsRemainGrouped(PhoneNumberUtil util, PhoneNumber number, StringBuilder normalizedCandidate, String[] formattedNumberGroups) { int fromIndex = 0; // Check each group of consecutive digits are not broken into separate groupings in the // {@code normalizedCandidate} string. for (int i = 0; i < formattedNumberGroups.length(); i++) { // Fails if the substring of {@code normalizedCandidate} starting from {@code fromIndex} // doesn't contain the consecutive digits in formattedNumberGroups[i]. fromIndex = normalizedCandidate.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. We get the region used for formatting // information based on the country code in the phone number, rather than the number itself, // as we do not need to distinguish between different countries with the same country // calling code and this is faster. String region = util.getRegionCodeForCountryCode(number.getCountryCode()); if (util.getNddPrefixForRegion(region, true) != null && Character.isDigit(normalizedCandidate.charAt(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. This is only important for countries with national prefixes. String nationalSignificantNumber = util.getNationalSignificantNumber(number); return(normalizedCandidate.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.substring(fromIndex).contains(number.getExtension())); }
/** * Attempts to set the formatting template and returns a string which contains the formatted * version of the digits entered so far. */ private String attemptToChooseFormattingPattern() { // We start to attempt to format only when at least MIN_LEADING_DIGITS_LENGTH digits of national // number (excluding national prefix) have been entered. if (nationalNumber.length() >= MIN_LEADING_DIGITS_LENGTH) { getAvailableFormats(nationalNumber.substring(0, MIN_LEADING_DIGITS_LENGTH)); // See if the accrued digits can be formatted properly already. String formattedNumber = attemptToFormatAccruedDigits(); if (formattedNumber.length() > 0) { return(formattedNumber); } return(maybeCreateNewTemplate() ? inputAccruedNationalNumber() : accruedInput.toString()); } else { return(appendNationalNumber(nationalNumber.toString())); } }
/** * Extracts IDD and plus sign to prefixBeforeNationalNumber when they are available, and places * the remaining input into nationalNumber. * * @return true when accruedInputWithoutFormatting begins with the plus sign or valid IDD for * defaultCountry. */ private boolean attemptToExtractIdd() { Pattern internationalPrefix = regexCache.getPatternForRegex("\\" + PhoneNumberUtil.PLUS_SIGN + "|" + currentMetadata.getInternationalPrefix()); Matcher iddMatcher = internationalPrefix.matcher(accruedInputWithoutFormatting); if (iddMatcher.lookingAt()) { isCompleteNumber = true; int startOfCountryCallingCode = iddMatcher.end(); nationalNumber.setLength(0); nationalNumber.append(accruedInputWithoutFormatting.substring(startOfCountryCallingCode)); prefixBeforeNationalNumber.setLength(0); prefixBeforeNationalNumber.append( accruedInputWithoutFormatting.substring(0, startOfCountryCallingCode)); if (accruedInputWithoutFormatting.charAt(0) != PhoneNumberUtil.PLUS_SIGN) { prefixBeforeNationalNumber.append(SEPARATOR_BEFORE_NATIONAL_NUMBER); } return(true); } return(false); }
private String inputDigitHelper(char nextChar) { Matcher digitMatcher = DIGIT_PATTERN.matcher(formattingTemplate); if (digitMatcher.find(lastMatchPosition)) { String tempTemplate = digitMatcher.replaceFirst(Character.toString(nextChar)); formattingTemplate.replace(0, tempTemplate.length(), tempTemplate); lastMatchPosition = digitMatcher.start(); return(formattingTemplate.substring(0, lastMatchPosition + 1)); } else { if (possibleFormats.size() == 1) { // More digits are entered than we could handle, and there are no other valid patterns to // try. ableToFormat = false; } // else, we just reset the formatting pattern. currentFormattingPattern = ""; return(accruedInput.toString()); } }