mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-07-30 16:49:55 +08:00
814364489f
Continue #12778 <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **Chores** - Removed internal string utility functions related to markdown prefix and horizontal rule detection. No impact on user-facing features. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
76 lines
1.9 KiB
TypeScript
76 lines
1.9 KiB
TypeScript
function escapeRegExp(input: string) {
|
|
// escape regex characters in the input string to prevent regex format errors
|
|
return input.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
}
|
|
|
|
/**
|
|
* Checks if the name is a fuzzy match of the query.
|
|
*
|
|
* @example
|
|
* ```ts
|
|
* const name = 'John Smith';
|
|
* const query = 'js';
|
|
* const isMatch = isFuzzyMatch(name, query);
|
|
* // isMatch: true
|
|
* ```
|
|
*/
|
|
export function isFuzzyMatch(name: string, query: string) {
|
|
const pureName = name
|
|
.trim()
|
|
.toLowerCase()
|
|
.split('')
|
|
.filter(char => char !== ' ')
|
|
.join('');
|
|
|
|
const regex = new RegExp(
|
|
query
|
|
.split('')
|
|
.filter(char => char !== ' ')
|
|
.map(item => `${escapeRegExp(item)}.*`)
|
|
.join(''),
|
|
'i'
|
|
);
|
|
return regex.test(pureName);
|
|
}
|
|
|
|
/**
|
|
* Calculate the score of the substring match.
|
|
* s = [0.5, 1] if the query is a substring of the name
|
|
* s = (0, 0.5) if there exists a common non-maximal length substring
|
|
* s = 0 if there is no match
|
|
*
|
|
* s is greater if the query has a longer substring.
|
|
*/
|
|
export function substringMatchScore(name: string, query: string) {
|
|
if (query.length === 0) return 0;
|
|
if (name.length === 0) return 0;
|
|
if (query.length > name.length) return 0;
|
|
|
|
query = query.toLowerCase();
|
|
name = name.toLocaleLowerCase();
|
|
|
|
let score;
|
|
if (name.includes(query)) {
|
|
score = 1 + query.length / name.length;
|
|
} else {
|
|
let maxMatchLength = 0;
|
|
for (let i = 0; i < query.length; i++) {
|
|
for (let j = 0; j < name.length; j++) {
|
|
let matchLength = 0;
|
|
while (
|
|
i + matchLength < query.length &&
|
|
j + matchLength < name.length &&
|
|
query[i + matchLength] === name[j + matchLength]
|
|
) {
|
|
matchLength++;
|
|
}
|
|
maxMatchLength = Math.max(maxMatchLength, matchLength);
|
|
}
|
|
}
|
|
score = maxMatchLength / name.length;
|
|
}
|
|
|
|
// normalize
|
|
return 0.5 * score;
|
|
}
|