UNPKG

refined-text-search

Version:

Tokenize a search query with refined options (like Google's) and match against a target

47 lines 1.72 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.match = exports.tokenizeClause = exports.tokenize = void 0; const pattern = /(=|-)?("[^"]*"|[^\s]+)/g; function tokenize(query) { query = query.toLowerCase().trim(); const orClauses = query.split(/ or | \| /); if (orClauses.length === 1) { return tokenizeClause(orClauses[0]); } return [{ or: true, children: orClauses.map(tokenizeClause) }]; } exports.tokenize = tokenize; function tokenizeClause(query) { const tokens = []; let matched; while ((matched = pattern.exec(query))) { const prefix = matched[1]; let term = matched[2]; term = term.replace(/(^"|"$)/g, ''); const exclude = prefix === '-' ? true : undefined; const exact = prefix === '=' ? true : undefined; tokens.push(Object.assign(Object.assign({ term }, (exclude ? { exclude } : {})), (exact ? { exact } : {}))); } tokens.sort((a, b) => (a.exclude === b.exclude ? 0 : a.exclude ? -1 : 1)); return tokens; } exports.tokenizeClause = tokenizeClause; function match(tokens, text) { text = text.replace(/\s+/g, ' ').trim().toLowerCase(); for (let i = 0; i !== tokens.length; i++) { const token = tokens[i]; if ('or' in token) { return token.children.some((childTokens) => match(childTokens, text)); } const textMatch = token.exact ? text === token.term : text.indexOf(token.term) !== -1; if (token.exclude && textMatch) { return false; } if (!token.exclude && !textMatch) { return false; } } return true; } exports.match = match; //# sourceMappingURL=index.js.map