Files
clash-verge-rev/src/utils/search-matcher.ts
T
Tunglies 7ca20fc4ed refactor: knip cleanup (#7468)
* chore(frontend): expand Knip reports

* chore: remove unused Mihomo changelog sync script

* refactor: remove unused value exports

* refactor: remove unused type exports

* refactor: remove circular route dependencies

* chore(frontend): move Knip scope to config

* chore(i18n): remove stale portable update message
2026-07-13 11:29:25 +08:00

60 lines
1.6 KiB
TypeScript

export type SearchMatcherOptions = {
matchCase?: boolean
matchWholeWord?: boolean
useRegularExpression?: boolean
}
export type CompileStringMatcherResult = {
matcher: (content: string) => boolean
isValid: boolean
}
const escapeRegex = (value: string) => {
return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
}
export const buildRegex = (pattern: string, flags = '') => {
try {
return new RegExp(pattern, flags)
} catch {
return null
}
}
export const compileStringMatcher = (
query: string,
options: SearchMatcherOptions = {},
): CompileStringMatcherResult => {
if (!query) return { matcher: () => true, isValid: true }
const matchCase = options.matchCase ?? false
const matchWholeWord = options.matchWholeWord ?? false
const useRegularExpression = options.useRegularExpression ?? false
const flags = matchCase ? '' : 'i'
if (useRegularExpression) {
const regex = buildRegex(query, flags)
if (!regex) return { matcher: () => false, isValid: false }
return { matcher: (content: string) => regex.test(content), isValid: true }
}
if (matchWholeWord) {
const regex = buildRegex(`\\b${escapeRegex(query)}\\b`, flags)
if (!regex) return { matcher: () => false, isValid: false }
return { matcher: (content: string) => regex.test(content), isValid: true }
}
if (matchCase) {
return {
matcher: (content: string) => content.includes(query),
isValid: true,
}
}
const target = query.toLowerCase()
return {
matcher: (content: string) => content.toLowerCase().includes(target),
isValid: true,
}
}