UNPKG

regexp-stack

Version:

This library allows to run regular expressions.

111 lines (105 loc) 3.36 kB
module.exports = class RegExpStack { constructor () { this.expStack = {}; this.globalLastIndex = 0; } add (name, exp, passNamingGroups) { var namingGroups = passNamingGroups; if (typeof namingGroups === 'string') namingGroups = passNamingGroups.split(/\s*[,;]\s*|\s+/); if (! (exp instanceof RegExp)) throw new TypeError ('RegExpStack::add 2nd argument must be the regular expression'); if (! exp.global && ! exp.sticky) throw new TypeError ('RegExpStack::add regular expression must be global (/g) or sticky (/y)'); if (namingGroups && !(namingGroups instanceof Array)) throw new TypeError ('RegExpStack::add 3rd argument must be an array with group names to set on result'); this.expStack[name] = { exp, names: namingGroups || [], } this['$'+name] = text=>this.match(name, text); this['all$'+name] = text=>this.all(name, text); this['each$'+name] = text=>this.each(name, text); return this; } reset () { this.globalLastIndex = 0; return this; } match (name, text) { var item = this.expStack[name]; item.exp.lastIndex = this.globalLastIndex; var result = item.exp.exec (text); if (! result) return result; this.globalLastIndex = item.exp.lastIndex; result = NormalizeResult (result, item.names); if (result) result.RegExp = item.exp; return result; } all (name, text) { var item, result = true; var stack = []; while (result) { item = this.expStack[name]; item.exp.lastIndex = this.globalLastIndex; result = item.exp.exec (text); this.globalLastIndex = item.exp.lastIndex; result = NormalizeResult (result, item.names); if (! result) break; stack.push (result); } return stack; } * each (name, text) { var item, result = true; while (result) { item = this.expStack[name]; item.exp.lastIndex = this.globalLastIndex; result = item.exp.exec (text); this.globalLastIndex = item.exp.lastIndex; result = NormalizeResult (result, item.names); if (! result) return; yield result; } } } function NormalizeResult (match, names) { if (! match) return match; var result = match; result.match = match[0]; if (! names.length) return match; if (names[0] === '') return {match}; var groupName, groupIndex; for ([groupIndex, groupName] of names.entries()) { if (groupName === '-') continue; if (result[groupName]) { if (typeof result[groupName] === 'function') throw new Error ('RegExp group name "'+groupName+'" conflicts with an array function, you must choose unique names to results'); else throw new Error ('RegExp group name "'+groupName+'" is already taken, use another name to your group'); } else result[groupName] = match[groupIndex+1]; } return result; }