Регистр первого символа каждого слова, которое состоит из трех и более символов, должен быть интвертирован. Как сделать чтоб работало и с кириллицей?

246
19 августа 2021, 10:30

Слово следует рассматривать как последовательность, содержащую только буквы (все остальные символы не являются частью слово). Например: Вход:

----------
When I was younger 
----------
I never needed 
----------
Прощай, со всех вокзалов поезда 
----------
уходят в Дальние Края
----------

Выход:

when I Was Younger
----------
I Never Needed
----------
прощай, со Всех Вокзалов Поезда
----------
Уходят в дальние края
----------

Код:

public static String toUp(String input) {
    StringBuilder resultBuilder = new StringBuilder();
    if (input.isEmpty()) {
        return input;
    } else {
        for (String word : input.split(" ")) {
            if (word.length() >= 3) {
                if (Character.isUpperCase(word.charAt(0))) {
                    word = Character.toLowerCase(word.charAt(0)) + word.substring(1);
                } else if (Character.isLowerCase(word.charAt(0))) {
                    word = Character.toUpperCase(word.charAt(0)) + word.substring(1);
                }
                resultBuilder.append(word).append(" ");
            } else {
                resultBuilder.append(word).append(" ");
            }
        }
        return resultBuilder.toString();
    }
}
Answer 1

Можно использовать

String s = "When I was younger\nI never needed\nПрощай, со всех вокзалов поезда\nуходят в Дальние Края";
Pattern p = Pattern.compile("\\b(?:(\\p{Lu})|\\p{Ll})(?=\\p{L}{2})");
// Если граница слова – пробельный символ, используйте
// Pattern p = Pattern.compile("(?<!\\S)(?:(\\p{Lu})|\\p{Ll})(?=\\p{L}{2})");
Matcher m = p.matcher(s);
System.out.println( m.replaceAll(r -> 
    r.group(1) == null ? r.group().toUpperCase() : r.group().toLowerCase()) 
);

См. пример работы кода онлайн

Регулярное выражение находит

  • \b - границу слова ((?<!\S) находит либо начало строки, либо позицию в строке, сразу перед которой есть пробельный символ)
  • (?:(\\p{Lu})|\\p{Ll}) - прописную (захватывая в подмаску №1) или строчную букву,
  • (?=\\p{L}{2}) - за которой следуют любые две буквы.

Если найдена прописная буква, она заменяется строчной и наоборот.

Answer 2

Оно уже работает с кириллицей. Добавьте в разделении на слова символ переноса строки: for (String word : input.split("[ \n]")). Проблема в том, что введеный из файла текст содержит между словами не только пробелы, но еще и перенос строки. Например, needed\nПрощай, не будет разделен на слова, потому что между needed и Прощай нет пробела, поэтому у некоторых слов из текста не будет изменен регистр первой буквы.

READ ALSO
Полиморфизм и позднее связывание в Java

Полиморфизм и позднее связывание в Java

У Эккеля есть замечательный пример полиморфизма:

301
Вытащить два первых символа из строки

Вытащить два первых символа из строки

Есть такая таблица в несколько колонок

104
Извлечь image из MultipartFile

Извлечь image из MultipartFile

Не подскажите как можно извлечь изображение которое храниться в MultipartFile?

184