JSFiddle - React, Tailwind, and code Playground
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/xregexp/3.2.0/xregexp-all.min.js"></script>
JavaScript
/**
* Реализация метода String.match() с учётом рекурсии
*
* @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/match
* @param {RegExp} pattern Регулярное выражение должно быть сконструировано с группой с двумя или более альтернативами. Формат:
* `(OpenPattern)|(ClosePattern)`
* `(OpenPattern)|(ClosePattern)|OuterAndInnerPattern`
* Если передан флаг 'g', то возвращается всегда массив.
* Иначе возвращается строка (если совпадение найдено) или Null (если совпадение не найдено).
* @param {Object} options Объект, в котором для регулярного выражения указываются номера карманов для открывающего и закрывающего совпадений.
* Пример: `{open: 1, close: 2}`
* @returns {Array|String|Null}
* @throws {Error} if maximum depth will be reached
* @author Mukhtarov Rinat <[email protected]>
*/
String.prototype.matchRecursive = function(pattern, options) {
var match, depth = 0, depthMax = 1000, item = 0, result = [], isOpen, isClose, global = pattern.global;
if (! global) pattern = RegExp(pattern.source, 'g' + (pattern.ignoreCase ? 'i' : '')
+ (pattern.multiline ? 'i' : ''));
while (match = pattern.exec(this)) {
isOpen = (typeof match[options.open] === 'string');
isClose = (typeof match[options.close] === 'string');
if (isOpen) depth++;
if (depth > 0) {
if (depth > depthMax) throw Error(depthMax + ' depth has been reached');
if (isOpen && typeof result[item] !== 'string') result[item] = '';
result[item] += this.substring(match.index, pattern.lastIndex);
if (depth === 1 && isClose) {
if (! global) break;
item++;
}
}
if (isClose) depth--;
}
if (! global) return result ? result.pop() : null;
return result;
}
//пример использования String.matchRecursive() -- получает...