Вот регулярное выражение, которое соответствует 5-буквенным последовательностям, которые включают все «a», «b» и «c»:
(?=.{0,4}a)(?=.{0,4}b)(?=.{0,4}c).{5}
Итак, хотя в основном совпадают любые 5 символов (с .{5}
), существует три предварительных условия, которым должны соответствовать соответствия. Каждый из них требует наличия одного из токенов / букв (до 4 символов, за которыми следует «а» и т. Д.). (?=X)
соответствует «X с положительным прогнозом нулевой ширины», где нулевая ширина означает, что позиция символа не изменяется при сопоставлении.
Делать это с регулярными выражениями довольно медленно, хотя ... Вот более прямая версия (кажется, примерно в 15 раз быстрее, чем при использовании регулярных выражений):
public static void find(String haystack, String tokens, int windowLen) {
char[] tokenChars = tokens.toCharArray();
int hayLen = haystack.length();
int pos = 0;
nextPos:
while (pos + windowLen <= hayLen) {
for (char c : tokenChars) {
int i = haystack.indexOf(c, pos);
if (i < 0) return;
if (i - pos >= windowLen) {
pos = i - windowLen + 1;
continue nextPos;
}
}
// match found at pos
System.out.println(pos + ".." + (pos + windowLen - 1) + ": " + haystack.substring(pos, pos + windowLen));
pos++;
}
}