Надо объединить возможности регулярных выражений, такие как жадный и ленивый поиск, захват подстроки в блоке просмотра и глобальный модификатор:
re = /(?=(a.*?b))(?=(a.*b))/g;
s = 'aabb';
arr = [];
while ((m=re.exec(s)) !== null) {
if (m.index === re.lastIndex) {
re.lastIndex++;
}
if (m[1] && arr.indexOf(m[1]) === -1)
arr.push(m[1]);
if (m[2] && arr.indexOf(m[2]) === -1)
arr.push(m[2]);
}
document.write(JSON.stringify(arr));
В данном случае, выражение при нахождении совпадения вернет пустой результат в m[0]
, но благодаря подмаскам в m[1]
и m[2]
будут извлечены захваченные подстроки. Так как эти подстроки могут быть идентичны, необходима проверка существующих элементов.
ОТВЕТ НА КОММЕНТАРИЙ:
Для поиска всех пермутаций на основе любого шаблона, можно воспользоваться следующим кодом. Его особенность: собираем все совпадения, а потом последовательно определяем, есть ли совпадения внутри совпадения. Таким образом, нет необходимости проверять абсолютно все пермутации входной строки.
function permRegex(re_str, s) {
var arr = []; // Все наши пермутации
var caps = []; // Все начальные совпадения (caps)
var re = RegExp(re_str, "g"); // Глобальное выражение для caps
while ((m = re.exec(s)) !== null) { // Ищем...
caps.push(m[0]); // и добавляем совпадение в caps
}
var re2 = RegExp("^" + re_str + "$"); // Создаем неглобальное выражение для проверки на совпадение ЦЕЛОЙ строки
for (var c=0; c<caps.length; c++) // Перебираем наши совпадения
for(var i=0; i < caps[c].length; i++) // От первого символа...
for(var j=i+1; j <= caps[c].length; j++) // До последнего, слева направо
if(re2.test(str = caps[c].substring(i, j))) // Если совпадает с шаблоном
arr.push(str); // Добавляем к пермутациям
return arr;
}
document.getElementById("a1").innerHTML = JSON.stringify(permRegex("a.*b", "aabb")) + "<br/>";
// "aabb" => ["aabb", "aab", "abb", "ab"]
document.getElementById("a1").innerHTML += JSON.stringify(permRegex("a.*b", "aabbb")) + "<br/>";
// "aabbb" => ["aabbb", "aabb", "aab", "abbb", "abb", "ab"]
document.getElementById("a1").innerHTML += JSON.stringify(permRegex("е.*т", "А где енот?"));
// "е.*т", "А где енот?" => ["е енот", "енот"]
function permRegex(re_str, s) {
var arr = []; // Все наши пермутации
var caps = []; // Все начальные совпадения (caps)
var re = RegExp(re_str, "g"); // Глобальное выражение для caps
while ((m = re.exec(s)) !== null) { // Ищем...
caps.push(m[0]); // и добавляем совпадение в caps
}
var re2 = RegExp("^" + re_str + "$"); // Создаем неглобальное выражение для проверки на совпадение ЦЕЛОЙ строки
for (var c=0; c<caps.length; c++) // Перебираем наши совпадения
for(var i=0; i < caps[c].length; i++) // От первого символа...
for(var j=i+1; j <= caps[c].length; j++) // До последнего, слева направо
if(re2.test(str = caps[c].substring(i, j))) // Если совпадает с шаблоном
arr.push(str); // Добавляем к пермутациям
return arr;
}
document.getElementById("a1").innerHTML = JSON.stringify(permRegex("a.*b", "aabb")) + "<br/>";
// "aabb" => ["aabb", "aab", "abb", "ab"]
document.getElementById("a1").innerHTML += JSON.stringify(permRegex("a.*b", "aabbb")) + "<br/>";
// "aabbb" => ["aabbb", "aabb", "aab", "abbb", "abb", "ab"]
document.getElementById("a1").innerHTML += JSON.stringify(permRegex("е.*т", "А где енот?"));
// "е.*т", "А где енот?" => ["е енот", "енот"]
$( "#run" ).on( "click", function() {
$( "#a1" ).html( JSON.stringify(permRegex( $( "#regex" ).val(), $( "#text" ).val() ) ) );
} );
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="regex" placeholder="regex" /> <input id="text" placeholder="text" /><br/>
<button id="run">Ok</button>
<div id="a1"/>