Хочу проверить строку на наличие хаотически выставленных букв разных регистров. Для примера строка на входе:
Это стрОка... это сТроКа.
Выходная строка:
Это строка... Это строка.
Установку первой буквы предложения делаю так:
private static final String DOT_REGEX = "\\s*(?<!\\.)\\.(?!\\.)\\s*";
private static final String MULTI_DOT_REGEX = "\\s*\\.{3}\\s*";
private static final String FORMAT_CASE = "(?:^| )^\\w" + "|" + MULTI_DOT_REGEX + "\\w" + "|" + DOT_REGEX + "\\w";
Функция которая обрабатывает строку и возвращает готовый результат:
private static String getFormatCaseString(String targetString){
Matcher matcher = Pattern.compile(FORMAT_CASE).matcher(targetString);
StringBuffer stringBuffer = new StringBuffer();
while (matcher.find()){
matcher.appendReplacement(stringBuffer, matcher.group().toUpperCase());
}
matcher.appendTail(stringBuffer);
return stringBuffer.toString();
}
Идея в том что бы разбить предложение на две группы: первая это первые буквы нового предложения (которые и устанавливаются в UpperCase) и вторая это все остальные буквы которые выставляются в нижнем регистре. Как это сделать?
Вы можете захватить первую букву (символ типа word) в первую захватывающую группу и весь текст до первой одиночной точки или троеточия в другую группу, а дальше применить имеющуюся логику для замены:
String targetString = "Это стрОка... это сТроКа.";
Matcher matcher = Pattern.compile("(?Us)(\\w)(.*?(?:\\.{3}|(?<!\\.)\\.(?!\\.)))").matcher(targetString);
StringBuffer stringBuffer = new StringBuffer();
while (matcher.find()){
matcher.appendReplacement(stringBuffer,
matcher.group(1).toUpperCase() +
matcher.group(2).toLowerCase()
);
}
matcher.appendTail(stringBuffer);
System.out.println(stringBuffer.toString());
// = Это строка... Это строка.
Подробности
(?Us) - модификаторы Pattern.UNICODE_CHARACTER_CLASS (чтобы \w находил и русские буквы) и Pattern.DOTALL (чтобы . находил символы перевода строки)(\\w) - Захватывающая группа №1: буква, цифра или _ (это значение будет приведено к верхнему регистру - matcher.group(1).toUpperCase())(.*?(?:\\.{3}|(?<!\\.)\\.(?!\\.))) - Захватывающая группа №2 (это значение будет приведено к нижнему регистру - matcher.group(2).toLowerCase()):
.*? - 0 и более любых символов, как можно меньше(?: - начало незахватывающей группы
\\.{3} - три точки| - или(?<!\\.)\\.(?!\\.) - точка, перед и за которой нет других точек) - конец незахватывающей группыСборка персонального компьютера от Artline: умный выбор для современных пользователей