diff --git a/UPDATELOG.md b/UPDATELOG.md index a345e0726..a70b632e9 100644 --- a/UPDATELOG.md +++ b/UPDATELOG.md @@ -12,6 +12,7 @@ - 修复将快捷键名称更名为 `Clash Verge`之后无法删除图标和无法删除注册表 - 修复`DNS`覆写 `fallback` `proxy server` `nameserver` `direct Nameserver` 字段支持留空 - 修复`DNS`覆写 `nameserver-policy` 字段无法正确识别 `geo` 库 +- 修复搜索框输入特殊字符崩溃 ### ✨ 新增功能 diff --git a/src/components/base/base-search-box.tsx b/src/components/base/base-search-box.tsx index a01789fd5..850510e95 100644 --- a/src/components/base/base-search-box.tsx +++ b/src/components/base/base-search-box.tsx @@ -1,11 +1,10 @@ import { Box, SvgIcon, TextField, styled } from "@mui/material"; import Tooltip from "@mui/material/Tooltip"; -import { ChangeEvent, useEffect, useRef, useState, useMemo } from "react"; - -import { useTranslation } from "react-i18next"; +import { ChangeEvent, useEffect, useMemo, useRef, useState } from "react"; import matchCaseIcon from "@/assets/image/component/match_case.svg?react"; import matchWholeWordIcon from "@/assets/image/component/match_whole_word.svg?react"; import useRegularExpressionIcon from "@/assets/image/component/use_regular_expression.svg?react"; +import { useTranslation } from "react-i18next"; export type SearchState = { text: string; @@ -35,6 +34,11 @@ const StyledTextField = styled(TextField)(({ theme }) => ({ }, })); +// 转义正则表达式特殊字符的函数 +const escapeRegExp = (string: string) => { + return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); +}; + export const BaseSearchBox = (props: SearchProps) => { const { t } = useTranslation(); const inputRef = useRef(null); @@ -66,11 +70,14 @@ export const BaseSearchBox = (props: SearchProps) => { let searchItem = !matchCase ? searchText.toLowerCase() : searchText; if (useRegularExpression) { - return new RegExp(searchItem).test(item); + const pattern = matchWholeWord + ? `\\b${escapeRegExp(searchItem)}\\b` + : escapeRegExp(searchItem); + return new RegExp(pattern).test(item); } if (matchWholeWord) { - return new RegExp(`\\b${searchItem}\\b`).test(item); + return new RegExp(`\\b${escapeRegExp(searchItem)}\\b`).test(item); } return item.includes(searchItem);