Как в replaceAll проверить пустая ли группа?
Пишу программу на java. Осуществляю отображение введенных данных по маске. Есть строчка с именем человека. В поле может быть Фамилия или Фамилия Имя Отчество (от 1 до 3 слов).
Маска выводит "Фамилия И." (Первое слово плюс первая буква второго слова плюс точка).
Для вывода использую replaceAll("\\s*(\\S{0,20})\\S*\\s*(\\S)?.*","$1 $2.").
При нынешнем выводе, если в поле одно слово я получаю "Фамилия .". Можно ли как-то если в поле 1 слово, не выводить точку?
Нужно Чтобы
"Фамилия" -> "Фамилия"
"Фамилия Имя" -> "Фамилия И."
"Фамилия Имя Отчество" -> "Фамилия И."
Для реализации думаю нужно исправить второй аргумент функции "$1 $2." так чтобы точка выводилось только если есть второй аргумент. Знаете как это сделать?
Ответы (1 шт):
Для пропуска однословных строк ваше регулярное выражение не должно их находить, используйте
String result = text.replaceFirst("^(\\S+)\\s+(\\S).*", "$1 $2.");
См. пример работы регулярного выражения.
Подробности
^- начало строки(\S+)- Подмаска №2: один и более непробельных символов\s+- один и более пробельных символов (\h+находит только горизонтальные пробелы)(\S)- Подмаска №2: один непробельный символ.*- осатльная часть строки.
Пример работы кода в Java:
List<String> strs = Arrays.asList("Фамилия Имя Отчество", "Фамилия Имя", "Фамилия");
for (String str : strs)
System.out.println(str.replaceFirst("^(\\S+)\\s+(\\S).*", "$1 $2."));
Результат:
Фамилия И.
Фамилия И.
Фамилия
Если вам нужно оставить регулярное выражение без изменений, а изменить только замену, вам придётся использовать что-то вроде
List<String> strs = Arrays.asList("Фамилия Имя Отчество", "Фамилия Имя", "Фамилия");
Pattern p = Pattern.compile("\\s*(\\S{0,20})\\S*\\s*(\\S)?.*");
for (String str : strs) {
Matcher m = p.matcher(str);
System.out.println(m.replaceAll(x -> x.group(1) + (x.group(2) == null ? "" : " " + x.group(2) + ".")) );
}
См. пример работы кода.