From aa0091324b413b280276f3e5e4bdc9b43a6ea573 Mon Sep 17 00:00:00 2001 From: dualfroz Date: Wed, 14 Oct 2026 19:27:14 +0200 Subject: [PATCH] fix match escaping for + and /, refs #726 --- .../match/methods/parseMatch/02-parseToken.js | 6 ++++-- tests/01-one/match/encoding.test.js | 16 ++++++++++++++++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/src/1-one/match/methods/parseMatch/02-parseToken.js b/src/1-one/match/methods/parseMatch/02-parseToken.js index 07252d8..55df529 100644 --- a/src/1-one/match/methods/parseMatch/02-parseToken.js +++ b/src/1-one/match/methods/parseMatch/02-parseToken.js @@ -73,7 +73,7 @@ const parseToken = function (w, opts, aliases) { } } //back-flags - if (end(w) === '+') { + if (end(w) === '+' && !w.endsWith('\\+')) { obj.greedy = true w = stripEnd(w) } @@ -98,7 +98,7 @@ const parseToken = function (w, opts, aliases) { } //regex - if (start(w) === '/' && end(w) === '/') { + if (start(w) === '/' && end(w) === '/' && w.length > 2) { w = stripBoth(w) if (opts.caseSensitive) { obj.use = 'text' @@ -225,6 +225,8 @@ const parseToken = function (w, opts, aliases) { //somehow handle encoded-chars? w = w.replace('\\*', '*') w = w.replace('\\.', '.') + w = w.replace('\\+', '+') + w = w.replace('\\/', '/') if (opts.caseSensitive) { obj.use = 'text' } else { diff --git a/tests/01-one/match/encoding.test.js b/tests/01-one/match/encoding.test.js index 84bc1a1..75b9582 100644 --- a/tests/01-one/match/encoding.test.js +++ b/tests/01-one/match/encoding.test.js @@ -2,6 +2,22 @@ import test from 'tape' import nlp from '../../lib/one.js' const here = '[one/match/encoding] ' +test('encoding-match:', function (t) { + let doc = nlp('it is + nice') + t.equal(doc.match('is \\+ nice').text(), 'is + nice', here + 'encode plus') + t.deepEqual(doc.match('\\+').out('array'), ['+'], here + 'plus alone') + t.deepEqual(doc.match('!\\+').out('array'), ['it', 'is', 'nice'], here + 'negative plus') + + doc = nlp('a / b c d') + t.deepEqual(doc.match('\\/').out('array'), ['/'], here + 'encode slash') + t.deepEqual(doc.match('/').out('array'), ['/'], here + 'slash is not a regex') + t.equal(doc.match('a \\/ b').text(), 'a / b', here + 'slash in sequence') + + doc = nlp('4 / 2 + 1') + t.deepEqual(doc.match('(\\+|\\/)').out('array'), ['/', '+'], here + 'encoded choices') + t.end() +}) + test('reserved-word-in-src:', function (t) { const r = nlp('buy eggs constructor yeah prototype') t.equal(r.has(`backburner`), false, here + 'single')