diff --git a/README.md b/README.md index 876c9f4..d0ee63b 100644 --- a/README.md +++ b/README.md @@ -85,6 +85,13 @@ The options passed in the method take precedence over the one passed in the cont Indicates whether comparisons should be case-sensitive. +### excludedChars + +* **Type**: `array of string` +* **Default**: `[]` + +List of characters that should be ignored in the pattern or in the word used for matching + ### includeMatches * **Type**: `boolean` diff --git a/src/index.test.ts b/src/index.test.ts index 8fcbf83..083cf98 100644 --- a/src/index.test.ts +++ b/src/index.test.ts @@ -188,6 +188,19 @@ describe('partial match test', () => { score: 4.4, }, }, + { + title: 'default conf: ignoring space', + pattern: 'my awesome text', + text: 'my-awesome-text', + config: { + excludedChars: [' '], + }, + result: { + original: 'my-awesome-text', + rendered: 'my-awesome-text', + score: 68.86666666666666, + }, + }, { title: 'rendering conf: fuzzy match', pattern: 'met', diff --git a/src/index.ts b/src/index.ts index 3a9f5f3..35911df 100644 --- a/src/index.ts +++ b/src/index.ts @@ -73,37 +73,11 @@ export function score(intervals: FuzzyMatchingInterval[], strLength: number): nu return result } -// generateMatchingInterval will iterate other the given text to find the different char that matched the given pattern -function generateMatchingInterval(pattern: string, text: string, idxText: number): null | { - score: number; - intervals: FuzzyMatchingInterval[] -} { - let patternIdx = 0; - const intervals = []; - for (let i = idxText; i < text.length && patternIdx < pattern.length;) { - if (text[i] === pattern[patternIdx]) { - const interval = { from: i, to: i } - patternIdx++; - i++; - for (let j = i; j < text.length && patternIdx < pattern.length && text[j] === pattern[patternIdx]; j++) { - interval.to = j - patternIdx++ - i = j - } - intervals.push(interval) - } - i++; - } - if (intervals.length === 0 || patternIdx !== pattern.length) { - return null; - } - return { score: score(intervals, text.length), intervals: intervals } -} - export interface FuzzyConfiguration { caseSensitive?: boolean; - // List of characters that should be ignored when searching the pattern in the string + // List of characters that should be ignored in the pattern or in the word used for matching excludedChars?: string[]; + // Whenever the result should contain the list of intervals. includeMatches?: boolean; // If true, results will be sorted based on the score. shouldSort?: boolean; @@ -211,7 +185,7 @@ export class Fuzzy { // For example, given the pattern `bac` and the text `babac` // instead of matching `ba, it will match ba which has a better score than the previous one. if (localText[i] === localPattern[0]) { - const matchingResult = generateMatchingInterval(localPattern, localText, i); + const matchingResult = this.generateMatchingInterval(localPattern, localText, i, conf); if (matchingResult === null) { break } @@ -272,6 +246,47 @@ export class Fuzzy { } return str } + + // generateMatchingInterval will iterate other the given text to find the different char that matched the given pattern + private generateMatchingInterval(pattern: string, text: string, idxText: number, conf?: FuzzyConfiguration): null | { + score: number; + intervals: FuzzyMatchingInterval[] + } { + let excludedChars: string[] = [] + if (conf?.excludedChars !== undefined) { + excludedChars = conf.excludedChars + } else if (this.conf.excludedChars !== undefined) { + excludedChars = this.conf.excludedChars + } + let patternIdx = 0; + const intervals = []; + for (let i = idxText; i < text.length && patternIdx < pattern.length;) { + if (excludedChars.includes(text[i])) { + i++ + continue + } + if (excludedChars.includes(pattern[patternIdx])) { + patternIdx++ + continue + } + if (text[i] === pattern[patternIdx]) { + const interval = { from: i, to: i } + patternIdx++; + i++; + for (let j = i; j < text.length && patternIdx < pattern.length && text[j] === pattern[patternIdx]; j++) { + interval.to = j + patternIdx++ + i = j + } + intervals.push(interval) + } + i++; + } + if (intervals.length === 0 || patternIdx !== pattern.length) { + return null; + } + return { score: score(intervals, text.length), intervals: intervals } + } } const fuz = new Fuzzy()