From 7de69bfb32a0238b8b21c95bcd5bf9dfca5a8752 Mon Sep 17 00:00:00 2001 From: Richard Frost Date: Thu, 28 Mar 2019 02:18:12 -0600 Subject: [PATCH] :bug: Fix exact match with edge punctuation --- src/script/lib/word.ts | 3 +++ test/lib/filter.spec.js | 23 +++++++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/src/script/lib/word.ts b/src/script/lib/word.ts index 70b95b87..040477b1 100644 --- a/src/script/lib/word.ts +++ b/src/script/lib/word.ts @@ -1,4 +1,5 @@ export default class Word { + private static readonly _edgePunctuationRegExp = /(^[,.'"!?%$]|[,.'"!?%$]$)/; private static readonly _escapeRegExp = /[\/\\^$*+?.()|[\]{}]/g; private static readonly _unicodeRegex = /[^\u0000-\u00ff]/; private static readonly _unicodeWordBoundary = '[\\s.,\'"+!?|-]'; @@ -21,6 +22,8 @@ export default class Word { // Work around for lack of word boundary support for unicode characters // /(^|[\s.,'"+!?|-]+)(word)([\s.,'"+!?|-]+|$)/giu return new RegExp('(^|' + Word._unicodeWordBoundary + '+)(' + Word.processPhrase(str, matchRepeated) + ')(' + Word._unicodeWordBoundary + '+|$)', 'giu'); + } else if (str.match(Word._edgePunctuationRegExp)) { // Begin or end with punctuation (not \w)) + return new RegExp('(^|\\s)(' + Word.processPhrase(str, matchRepeated) + ')(\\s|$)', 'giu'); } else { return new RegExp('\\b' + Word.processPhrase(str, matchRepeated) + '\\b', 'gi'); } diff --git a/test/lib/filter.spec.js b/test/lib/filter.spec.js index 1b057eff..ddd926e2 100644 --- a/test/lib/filter.spec.js +++ b/test/lib/filter.spec.js @@ -178,6 +178,29 @@ describe('Filter', function() { expect(filter.replaceText('I love having good examples as an Exxaammppllee.')).to.equal('I love having good examples as an [Demo].'); }); + it('Should filter an exact word ending with punctuation', function() { + let filter = new Filter; + filter.cfg = new Config( + { + filterMethod: 1, + globalMatchMethod: 3, + substitutionMark: false, + preserveCase: true, + words: { + 'this!': { matchMethod: 0, repeat: false, sub: 'that!' }, + '!bang': { matchMethod: 0, repeat: true, sub: '!poof' }, + '!another!': { matchMethod: 0, repeat: false, sub: '$znother#' } + }, + } + ); + filter.init(); + expect(filter.replaceText('I love This! Do you?')).to.equal('I love That! Do you?'); + expect(filter.replaceText('I love this!')).to.equal('I love that!'); + expect(filter.replaceText('Go out with a !baangg')).to.equal('Go out with a !poof'); + expect(filter.replaceText('Go out with a !Bang!')).to.equal('Go out with a !Bang!'); + expect(filter.replaceText('!ANOTHER! so cool!')).to.equal('$ZNOTHER# so cool!'); + }); + it('Should filter an partial word with substitions not marked and preserveCase', function() { let filter = new Filter; filter.cfg = new Config({ words: Object.assign({}, testWords), filterMethod: 1, globalMatchMethod: 3, substitutionMark: false, preserveCase: true });