Наложение вхождений в RegEx Java
Необходимо найти все позиции вхождений в строке через регулярное выражение.
Пример:
Строка: cgcgcgcgcgcg
Вхождение: cgcg
Использую:
Pattern pattern = Pattern.compile("cgcg");
Matcher matcher = pattern.matcher("cgcgcgcgcgcg");
while (matcher.find())
System.out.println(matcher.start());
Результат:
0
4
8
А ожидаю получить:
0
2
4
6
8
Как учесть все вхождения, включая те, которые будут накладываться?
UPD. Получилось сделать так, но есть ли более адекватный способ?
Pattern pattern = Pattern.compile("cgcg");
Matcher matcher = pattern.matcher("cgcgcgcgcgcg");
int start = 0;
while (matcher.find(start)) {
start = matcher.start() + 1;
System.out.println(matcher.start());
}
Ответы (1 шт):
Автор решения: Wiktor Stribiżew
→ Ссылка
Вам нужно найти все пересекающиеся совпадения с различными начальными позициями в строке. Это можно сделать с помощью регулярного выражения. Для этого вам понадобится позитивный блок предварительного просмотра вперёд и захватывающая подмаска:
String regex = "cgcg";
Pattern pattern = Pattern.compile("(?=(" + regex + "))");
// Если regex не шаблон, а простой текст, экранируйте его перед использованием в REGEX
// Pattern pattern = Pattern.compile("(?=(" + Pattern.quote(regex) + "))");
Matcher matcher = pattern.matcher("cgcgcgcgcgcg");
while (matcher.find())
System.out.println(matcher.start(1));
С использованием streams:
List<Integer> results = pattern.matcher("cgcgcgcgcgcg")
.results()
.map(r -> r.start(1))
.collect(Collectors.toList());
Результат:
0
2
4
6
8
и
[0, 2, 4, 6, 8]