Извлечь подстроку между двумя определенными словами, используя регулярное выражение в java

Я хотел бы извлечь подстроку между некоторыми двумя словами, используя java.

Например:

This is an important example about regex for my work.

Я хотел бы извлечь все между "an" и "for".

Что я сделал до сих пор:

String sentence = "This is an important example about regex for my work and for me";
Pattern pattern = Pattern.compile("(?<=an).*.(?=for)");
Matcher matcher = pattern.matcher(sentence);

boolean found = false;
while (matcher.find()) {
    System.out.println("I found the text: " + matcher.group().toString());
    found = true;
}
if (!found) {
    System.out.println("I didn't found the text");
}

Хорошо работает.

Но я хочу сделать еще две вещи

  • Если предложение: This is an important example about regex for my work and for me. Я хочу извлечь до первого "for" i.e. important example about regex

  • Несколько раз я хочу ограничить количество слов между шаблоном до 3 слов, т.е. important example about

Любые идеи, пожалуйста?

Ответ 1

Для вашего первого вопроса сделайте его ленивым. Вы можете поставить знак вопроса после квантификатора, а затем квантификатор будет как можно меньше.

(?<=an).*?(?=for)

Я понятия не имею, что дополнительный . в конце хорош для .*. его ненужного.

Для вашего второго вопроса вы должны определить, что такое "слово". Я бы сказал, что здесь, вероятно, просто последовательность без пробелов, за которой следует пробел. Что-то вроде этого

\S+\s

и повторите это 3 раза, как это

(?<=an)\s(\S+\s){3}(?=for)

Чтобы гарантировать, что в шаблонах mathces для целых слов используются границы слов

(?<=\ban\b)\s(\S+\s){1,5}(?=\bfor\b)

Смотрите онлайн здесь, в Regexr

{3} будет соответствовать точно 3 для минимума 1 и максимум 3 сделать это {1,3}

Альтернатива:

Поскольку dma_k правильно указано в вашем случае, здесь не нужно использовать внешний вид и смотреть вперед. См. здесь документацию о сопоставлении групп.

Вместо этого вы можете использовать группы захвата. Просто поставьте часть, которую вы хотите извлечь в скобках, и она будет помещена в группу захвата.

\ban\b(.*?)\bfor\b

Смотрите онлайн здесь, в Regexr

Вы можете получить доступ к этой группе, подобной этой

System.out.println("I found the text: " + matcher.group(1).toString());
                                                        ^

У вас есть только одна пара скобок, поэтому просто, просто поместите 1 в matcher.group(1) для доступа к первой группе захвата.

Ответ 2

Ваше регулярное выражение "an\\s+(.*?)\\s+for". Он извлекает все символы между а и для игнорирования пробелов (\s+). Значок вопроса означает "жадный". Это необходимо для предотвращения шаблона .*, чтобы съесть все, включая слово "для".

Ответ 3

открытый класс SubStringBetween {

public static String subStringBetween(String sentence, String before, String after) {

    int startSub = SubStringBetween.subStringStartIndex(sentence, before);
    int stopSub = SubStringBetween.subStringEndIndex(sentence, after);

    String newWord = sentence.substring(startSub, stopSub);
    return newWord;
}

public static int subStringStartIndex(String sentence, String delimiterBeforeWord) {

    int startIndex = 0;
    String newWord = "";
    int x = 0, y = 0;

    for (int i = 0; i < sentence.length(); i++) {
        newWord = "";

        if (sentence.charAt(i) == delimiterBeforeWord.charAt(0)) {
            startIndex = i;
            for (int j = 0; j < delimiterBeforeWord.length(); j++) {
                try {
                    if (sentence.charAt(startIndex) == delimiterBeforeWord.charAt(j)) {
                        newWord = newWord + sentence.charAt(startIndex);
                    }
                    startIndex++;
                } catch (Exception e) {
                }

            }
            if (newWord.equals(delimiterBeforeWord)) {
                x = startIndex;
            }
        }
    }
    return x;
}

public static int subStringEndIndex(String sentence, String delimiterAfterWord) {

    int startIndex = 0;
    String newWord = "";
    int x = 0;

    for (int i = 0; i < sentence.length(); i++) {
        newWord = "";

        if (sentence.charAt(i) == delimiterAfterWord.charAt(0)) {
            startIndex = i;
            for (int j = 0; j < delimiterAfterWord.length(); j++) {
                try {
                    if (sentence.charAt(startIndex) == delimiterAfterWord.charAt(j)) {
                        newWord = newWord + sentence.charAt(startIndex);
                    }
                    startIndex++;
                } catch (Exception e) {
                }

            }
            if (newWord.equals(delimiterAfterWord)) {
                x = startIndex;
                x = x - delimiterAfterWord.length();
            }
        }
    }
    return x;
}

}