@awayfl/avm2
Version:
Virtual machine for executing AS3 code
87 lines (86 loc) • 3.47 kB
JavaScript
/* eslint-disable no-cond-assign */
import XRegExpOrig from 'xregexp/lib';
(function (XRegExp) {
function preparePattern(pattern, flags) {
var lbOpen, lbEndPos, lbInner;
flags = flags || '';
// Extract flags from a leading mode modifier, if present
pattern = pattern.replace(/^\(\?([\w$]+)\)/, function ($0, $1) {
flags += $1;
return '';
});
if (lbOpen = /^\(\?<([=!])/.exec(pattern)) {
// Extract the lookbehind pattern. Allows nested groups, escaped parens, and unescaped parens within classes
lbEndPos = XRegExp.matchRecursive(pattern, /\((?:[^()[\\]|\\.|\[(?:[^\\\]]|\\.)*])*/.source, '\\)', 's', {
valueNames: [null, null, null, 'right'],
escapeChar: '\\'
})[0].end;
lbInner = pattern.slice('(?<='.length, lbEndPos - 1);
}
else {
throw new Error('lookbehind not at start of pattern');
}
return {
lb: XRegExp('(?:' + lbInner + ')$(?!\\s)', flags.replace(/[gy]/g, '')),
lbType: lbOpen[1] === '=',
main: XRegExp(pattern.slice(('(?<=)' + lbInner).length), flags)
};
}
XRegExp.execLb = function (str, pattern, flags) {
var pos = 0, match, leftContext;
var rex = preparePattern(pattern, flags);
while (match = XRegExp.exec(str, rex.main, pos)) {
leftContext = str.slice(0, match.index);
if (rex.lbType === rex.lb.test(leftContext)) {
return match;
}
pos = match.index + 1;
}
return null;
};
XRegExp.testLb = function (str, pattern, flags) {
return !!XRegExp.execLb(str, pattern, flags);
};
XRegExp.searchLb = function (str, pattern, flags) {
var match = XRegExp.execLb(str, pattern, flags);
return match ? match.index : -1;
};
XRegExp.matchAllLb = function (str, pattern, flags) {
var matches = [];
var pos = 0, match, leftContext;
var rex = preparePattern(pattern, flags);
while (match = XRegExp.exec(str, rex.main, pos)) {
leftContext = str.slice(0, match.index);
if (rex.lbType === rex.lb.test(leftContext)) {
matches.push(match[0]);
pos = match.index + (match[0].length || 1);
}
else {
pos = match.index + 1;
}
}
return matches;
};
XRegExp.replaceLb = function (str, pattern, replacement, flags) {
var output = '', pos = 0, lastEnd = 0, match, leftContext;
var rex = preparePattern(pattern, flags);
while (match = XRegExp.exec(str, rex.main, pos)) {
leftContext = str.slice(0, match.index);
if (rex.lbType === rex.lb.test(leftContext)) {
// Doesn't work correctly if lookahead in regex looks outside of the match
output += str.slice(lastEnd, match.index) + XRegExp.replace(match[0], rex.main, replacement);
lastEnd = match.index + match[0].length;
if (!rex.main.global) {
break;
}
pos = match.index + (match[0].length || 1);
}
else {
pos = match.index + 1;
}
}
return output + str.slice(lastEnd);
};
}(XRegExpOrig));
var XRegExp = XRegExpOrig;
export { XRegExp };