Извлечь подстроку между двумя определенными словами, используя регулярное выражение в 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;
}
}