Как использовать Java Regex для поиска всех повторяющихся последовательностей символов в строке?
Разбор случайной строки, которая ищет повторяющиеся последовательности с использованием Java и Regex.
Рассмотрим строки:
aaabbaaacccbb
Я хотел бы найти регулярное выражение, которое найдет все совпадения в приведенной выше строке:
aaabbaaacccbb
^^^ ^^^
aaabbaaacccbb
^^ ^^
Что представляет собой выражение регулярного выражения, которое будет проверять строку для любых повторяющихся последовательностей символов и возвращать группы этих повторяющихся символов таким образом, что группа 1 = aaa и группа 2 = bb. Также обратите внимание, что я использовал примерную строку, но все повторяющиеся символы действительны:
RonRonJoeJoe
......,,...,
Ответы
Ответ 1
Это делает:
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Test {
public static void main(String[] args) {
String s = "aaabbaaacccbb";
find(s);
String s1 = "RonRonRonJoeJoe .... ,,,,";
find(s1);
System.err.println("---");
String s2 = "RonBobRonJoe";
find(s2);
}
private static void find(String s) {
Matcher m = Pattern.compile("(.+)\\1+").matcher(s);
while (m.find()) {
System.err.println(m.group());
}
}
}
ВЫВОД:
aaa
bb
aaa
ccc
bb
RonRonRon
JoeJoe
....
,,,,
---
Ответ 2
Ниже следует работать для всех требований. На самом деле это комбинация из нескольких ответов здесь, и она выведет все подстроки, которые повторяются в другом месте в строке.
Я установил его, чтобы возвращать подстроки не менее двух символов, но его можно легко изменить на отдельные символы, изменив "{2,}" в регулярном выражении на "+".
public static void main(String[] args)
{
String s = "RonSamJoeJoeSamRon";
Matcher m = Pattern.compile("(\\S{2,})(?=.*?\\1)").matcher(s);
while (m.find())
{
for (int i = 1; i <= m.groupCount(); i++)
{
System.out.println(m.group(i));
}
}
}
Выход:
Рон
Сэм
Джо
Ответ 3
Вы можете использовать это регулярное выражение positive lookahead
:
((\\w)\\2+)(?=.*\\1)
Код:
String elem = "aaabbaaacccbb";
String regex = "((\\w)\\2+)(?=.*\\1)";
Pattern p = Pattern.compile(regex);
Matcher matcher = p.matcher(elem);
for (int i=1; matcher.find(); i++)
System.out.println("Group # " + i + " got: " + matcher.group(1));
ВЫВОД:
Group # 1 got: aaa
Group # 2 got: bb
Ответ 4
Это похоже на работу, хотя и дает подпоследовательности:
(Чтобы быть справедливым, это было построено на основе кода Гийима)
public static void main(final String[] args) {
// final String s = "RonRonJoeJoe";
// final String s = "RonBobRonJoe";
final String s = "aaabbaaacccbb";
final Pattern p = Pattern.compile("(.+).*\\1");
final Matcher m = p.matcher(s);
int start = 0;
while (m.find(start)) {
System.out.println(m.group(1));
start = m.toMatchResult().end(1);
}
}
Ответ 5
Вы можете игнорировать совпадение.
// overlapped 1 or more chars
(?=(\w{1,}).*\1)
// overlapped 2 or more chars
(?=(\w{2,}).*\1)
// overlapped 3 or more chars, etc ..
(?=(\w{3,}).*\1)
Или вы могли бы потреблять (без перекрытия)..
// 1 or more chars
(?=(\w{1,}).*\1) \1
// 2 or more chars
(?=(\w{2,}).*\1) \1
// 3 or more chars, etc ..
(?=(\w{3,}).*\1) \1