Как найти слова, начинающиеся после переноса строки, используя регулярные выражения, Java? - PullRequest
0 голосов
/ 09 октября 2019

У меня есть входная строка, состоящая из нескольких строк, например:

When I was younger
I never needed
And I was always OK
but it was a long Time Ago

Проблема состоит в том, чтобы инвертировать первые буквы всех слов, длина которых превышает 3. То есть вывод должен бытьследующее:

when I Was Younger
I Never Needed
and I Was Always OK
But it Was a Long time ago

Вот мой код:

import java.util.regex.*;

public class Part3_1 {

    public static void main(String[] args) {
        String str = "When I was younger\r\nI never needed\r\nAnd I was always OK\r\nbut it was a long Time Ago";
        System.out.println(convert(str));
}

    public static String convert(String str) {
        String result = "";
        String[] strings = str.split(" ");
        String regexLowerCase = "\\b[a-z]{3,}\\b";
        String regexLowerCaseInitial = "(\\r\\n)[a-z]{3,}\\b";
        String regexUpperCase = "\\b([A-Z][a-z]{2,})+\\b";
        String regexUpperCaseInitial = "(\\r\\n)([A-Z][a-z]{2,})\\b";
        Pattern patternLowerCase = Pattern.compile(regexLowerCase, Pattern.MULTILINE);
        Pattern patternUpperCase = Pattern.compile(regexUpperCase, Pattern.MULTILINE);
        Pattern patternLowerCaseInitial = Pattern.compile(regexLowerCaseInitial, Pattern.MULTILINE);
        Pattern patternUpperCaseInitial = Pattern.compile(regexUpperCaseInitial, Pattern.MULTILINE);

        for (int i = 0; i < strings.length; i++) {
            Matcher matcherLowerCase = patternLowerCase.matcher(strings[i]);
            Matcher matcherUpperCase = patternUpperCase.matcher(strings[i]);
            Matcher matcherLowerCaseInitial = patternLowerCaseInitial.matcher(strings[i]);
            Matcher matcherUpperCaseInitial = patternUpperCaseInitial.matcher(strings[i]);
            char[] words = strings[i].toCharArray();
            if (matcherLowerCase.find() || matcherLowerCaseInitial.find()) {
                char temp = Character.toUpperCase(words[0]);
                words[0] = temp;
                result += new String(words);
            } else if (matcherUpperCase.find() || matcherUpperCaseInitial.find()) {
                char temp = Character.toLowerCase(words[0]);
                words[0] = temp;
                result += new String(words);
            } else {
                result += new String(words);
            }

            if (i < strings.length - 1) { 
                result += " "; 
            } 
        }
        return result;
    }
}

Здесь:

  • "\\b[a-z]{3,}\\b" - это регулярное выражение, выбирающее все слова в нижнем регистредлина которого составляет 3 или более символов,
  • "\\b([A-Z][a-z]{2,})+\\b" является регулярным выражением, выбирающим все слова, начинающиеся с заглавной буквы, длина которого составляет 3 или более символов.

Оба регулярных выражения работаютправильно, но когда у нас разрывы строк - они не работают. Результат выполнения моей программы следующий:

when I Was Younger
I Never Needed
And I Was Always OK
but it Was a Long Time ago

Как я понял, эти регулярные выражения не могут выбирать слова And и but из needed\r\nAnd и OK\r\nbut соответственно.

Чтобы исправить эту ошибку, я попытался добавить новые регулярные выражения "(\\r\\n)[a-z]{3,}\\b" и "(\\r\\n)([A-Z][a-z]{2,})\\b", но они не работают.

Как составить регулярные выражения, выбирая слова после переносов строк?

1 Ответ

1 голос
/ 09 октября 2019

Один из вариантов - вместо этого разбить строку на разрыв слова (\b), а затем пропустить пробел до последней строки в массиве strings. Это избавляет от необходимости иметь отдельное регулярное выражение для различных ситуаций, а также от необходимости добавлять символы пробела. Это даст вам нужные результаты:

public static String convert(String str) {
    String result = "";
    String[] strings = str.split("\\b");
    String regexLowerCase = "^[a-z]{3,}";
    String regexUpperCase = "^[A-Z][a-z]{2,}+";
    Pattern patternLowerCase = Pattern.compile(regexLowerCase, Pattern.MULTILINE);
    Pattern patternUpperCase = Pattern.compile(regexUpperCase, Pattern.MULTILINE);

    for (int i = 0; i < strings.length; i++) {
        Matcher matcherLowerCase = patternLowerCase.matcher(strings[i]);
        Matcher matcherUpperCase = patternUpperCase.matcher(strings[i]);
        char[] words = strings[i].toCharArray();
        if (matcherLowerCase.find()) {
            char temp = Character.toUpperCase(words[0]);
            words[0] = temp;
            result += new String(words);
        } else if (matcherUpperCase.find()) {
            char temp = Character.toLowerCase(words[0]);
            words[0] = temp;
            result += new String(words);
        } else {
            result += new String(words);
        }

    }
    return result;
}

Вывод:

when I Was Younger
I Never Needed
and I Was Always OK
But it Was a Long time ago

Демонстрация на rextester

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...