compromise
Version:
natural language processing in the browser
87 lines (81 loc) • 2.07 kB
JavaScript
;
// parse a search lookup term find the regex-like syntax in this term
const fns = require('./paths').fns;
//turn 'regex-like' search string into parsed json
const parse_term = function (term, i) {
term = term || '';
term = term.trim();
let reg = {};
//order matters..
//negation ! flag
if (fns.startsWith(term, '!')) {
term = term.substr(1, term.length);
reg.negative = true;
}
//leading ^ flag
if (fns.startsWith(term, '^')) {
term = term.substr(1, term.length);
reg.starting = true;
}
//trailing $ flag means ending
if (fns.endsWith(term, '$')) {
term = term.replace(/\$$/, '');
reg.ending = true;
}
//optional flag
if (fns.endsWith(term, '?')) {
term = term.replace(/\?$/, '');
reg.optional = true;
}
//atleast-one-but-greedy flag
if (fns.endsWith(term, '+')) {
term = term.replace(/\+$/, '');
reg.optional = false;
reg.consecutive = true;
}
//pos flag
if (fns.startsWith(term, '#')) {
term = term.replace(/^\#/, '');
reg.tag = [fns.titleCase(term)]
term = null;
}
//one_of options flag
if (fns.startsWith(term, '(') && fns.endsWith(term, ')')) {
term = term.replace(/\)$/, '');
term = term.replace(/^\(/, '');
reg.oneOf = term.split(/\|/g)
term = null;
}
//min/max any '{1,3}'
if (fns.startsWith(term, '{') && fns.endsWith(term, '}')) {
let m = term.match(/\{([0-9]+), ?([0-9]+)\}/);
reg.minMax = {
min: parseInt(m[1], 10),
max: parseInt(m[2], 10)
};
term = null;
}
//a period means any one term
if (term === '.') {
reg.anyOne = true;
term = null;
}
//a * means anything until sentence end
if (term === '*') {
reg.astrix = true;
term = null;
}
reg.normal = term;
if (reg.normal) {
reg.normal = reg.normal.toLowerCase();
}
return reg;
};
//turn a match string into an array of objects
const parse_all = function (reg) {
reg = reg || ''
reg = reg.split(/ +/);
return reg.map(parse_term);
};
// console.log(parse_all(''));
module.exports = parse_all;