143 lines
5.0 KiB
TypeScript
143 lines
5.0 KiB
TypeScript
define("regex", () => {
|
|
var RegExp = env.global.RegExp = env.internals.RegExp;
|
|
|
|
setProps(RegExp.prototype as RegExp, env, {
|
|
[Symbol.typeName]: 'RegExp',
|
|
|
|
test(val) {
|
|
return !!this.exec(val);
|
|
},
|
|
toString() {
|
|
return '/' + this.source + '/' + this.flags;
|
|
},
|
|
|
|
[Symbol.match](target) {
|
|
if (this.global) {
|
|
const res: string[] = [];
|
|
let val;
|
|
while (val = this.exec(target)) {
|
|
res.push(val[0]);
|
|
}
|
|
this.lastIndex = 0;
|
|
return res;
|
|
}
|
|
else {
|
|
const res = this.exec(target);
|
|
if (!this.sticky) this.lastIndex = 0;
|
|
return res;
|
|
}
|
|
},
|
|
[Symbol.matchAll](target) {
|
|
let pattern: RegExp | undefined = new this.constructor(this, this.flags + "g") as RegExp;
|
|
|
|
return {
|
|
next: (): IteratorResult<RegExpResult, undefined> => {
|
|
const val = pattern?.exec(target);
|
|
|
|
if (val === null || val === undefined) {
|
|
pattern = undefined;
|
|
return { done: true };
|
|
}
|
|
else return { value: val };
|
|
},
|
|
[Symbol.iterator]() { return this; }
|
|
}
|
|
},
|
|
[Symbol.split](target, limit, sensible) {
|
|
const pattern = new this.constructor(this, this.flags + "g") as RegExp;
|
|
let match: RegExpResult | null;
|
|
let lastEnd = 0;
|
|
const res: string[] = [];
|
|
|
|
while ((match = pattern.exec(target)) !== null) {
|
|
let added: string[] = [];
|
|
|
|
if (match.index >= target.length) break;
|
|
|
|
if (match[0].length === 0) {
|
|
added = [ target.substring(lastEnd, pattern.lastIndex), ];
|
|
if (pattern.lastIndex < target.length) added.push(...match.slice(1));
|
|
}
|
|
else if (match.index - lastEnd > 0) {
|
|
added = [ target.substring(lastEnd, match.index), ...match.slice(1) ];
|
|
}
|
|
else {
|
|
for (let i = 1; i < match.length; i++) {
|
|
res[res.length - match.length + i] = match[i];
|
|
}
|
|
}
|
|
|
|
if (sensible) {
|
|
if (limit !== undefined && res.length + added.length >= limit) break;
|
|
else res.push(...added);
|
|
}
|
|
else {
|
|
for (let i = 0; i < added.length; i++) {
|
|
if (limit !== undefined && res.length >= limit) return res;
|
|
else res.push(added[i]);
|
|
}
|
|
}
|
|
|
|
lastEnd = pattern.lastIndex;
|
|
}
|
|
|
|
if (lastEnd < target.length) {
|
|
res.push(target.substring(lastEnd));
|
|
}
|
|
|
|
return res;
|
|
},
|
|
[Symbol.replace](target, replacement) {
|
|
const pattern = new this.constructor(this, this.flags + "d") as RegExp;
|
|
let match: RegExpResult | null;
|
|
let lastEnd = 0;
|
|
const res: string[] = [];
|
|
|
|
// log(pattern.toString());
|
|
|
|
while ((match = pattern.exec(target)) !== null) {
|
|
const indices = match.indices![0];
|
|
res.push(target.substring(lastEnd, indices[0]));
|
|
if (replacement instanceof Function) {
|
|
res.push(replacement(target.substring(indices[0], indices[1]), ...match.slice(1), indices[0], target));
|
|
}
|
|
else {
|
|
res.push(replacement);
|
|
}
|
|
lastEnd = indices[1];
|
|
if (!pattern.global) break;
|
|
}
|
|
|
|
if (lastEnd < target.length) {
|
|
res.push(target.substring(lastEnd));
|
|
}
|
|
|
|
return res.join('');
|
|
},
|
|
[Symbol.search](target, reverse, start) {
|
|
const pattern: RegExp | undefined = new this.constructor(this, this.flags + "g") as RegExp;
|
|
|
|
|
|
if (!reverse) {
|
|
pattern.lastIndex = (start as any) | 0;
|
|
const res = pattern.exec(target);
|
|
if (res) return res.index;
|
|
else return -1;
|
|
}
|
|
else {
|
|
start ??= target.length;
|
|
start |= 0;
|
|
let res: RegExpResult | null = null;
|
|
|
|
while (true) {
|
|
const tmp = pattern.exec(target);
|
|
if (tmp === null || tmp.index > start) break;
|
|
res = tmp;
|
|
}
|
|
|
|
if (res && res.index <= start) return res.index;
|
|
else return -1;
|
|
}
|
|
},
|
|
});
|
|
}); |