fix: Fix the issue where global search matches special characters#272
fix: Fix the issue where global search matches special characters#272pengfeixx wants to merge 1 commit intolinuxdeepin:masterfrom
Conversation
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: pengfeixx The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
Reviewer's GuideThis PR tightens pinyin detection and normalizes pinyin search keywords to strip non‑letter characters, and adds a special-character matching layer (including half/full-width equivalence) so global filename search only matches files whose punctuation actually corresponds to the search keyword while still allowing relaxed matches when the keyword has no punctuation. Sequence diagram for filename search with pinyin normalization and special-character matchingsequenceDiagram
actor User
participant SearchUI
participant FileNameWorkerPrivate
participant FileSearchUtils
participant SearchFactory
participant SearchBackend
User->>SearchUI: enter keyword
SearchUI->>FileNameWorkerPrivate: startSearch(keyword, searchInfo)
loop buildSearchQuery
FileNameWorkerPrivate->>FileNameWorkerPrivate: createSearchQuery()
FileNameWorkerPrivate->>FileSearchUtils: hasWildcard(keyword)
FileSearchUtils-->>FileNameWorkerPrivate: bool
alt queryType is Simple
FileNameWorkerPrivate->>FileSearchUtils: isPinyin(keyword)
FileSearchUtils-->>FileNameWorkerPrivate: bool
alt keyword_is_pinyin
FileNameWorkerPrivate->>FileSearchUtils: normalizePinyinKeyword(keyword)
FileSearchUtils-->>FileNameWorkerPrivate: normalizedKeyword
FileNameWorkerPrivate->>SearchFactory: createQuery(normalizedKeyword, Simple)
else keyword_not_pinyin
FileNameWorkerPrivate->>SearchFactory: createQuery(keyword, Simple)
end
else queryType is Wildcard
FileNameWorkerPrivate->>SearchFactory: createQuery(keyword, Wildcard)
end
SearchFactory-->>FileNameWorkerPrivate: SearchQuery
end
FileNameWorkerPrivate->>SearchBackend: execute(SearchQuery)
SearchBackend-->>FileNameWorkerPrivate: candidateFileName
loop for each candidateFileName
FileNameWorkerPrivate->>FileSearchUtils: isPinyin(searchInfo.keyword)
FileSearchUtils-->>FileNameWorkerPrivate: bool
alt keyword_is_pinyin
FileNameWorkerPrivate->>FileSearchUtils: matchSpecialChars(candidateFileName, searchInfo.keyword)
FileSearchUtils->>FileSearchUtils: extract searchSpecialChars
FileSearchUtils->>FileSearchUtils: extract fileSpecialChars
FileSearchUtils->>FileSearchUtils: charsEquivalent(searchChar, fileChar)
FileSearchUtils-->>FileNameWorkerPrivate: bool
alt special_chars_match
FileNameWorkerPrivate->>FileNameWorkerPrivate: appendSearchResult(candidateFileName)
else special_chars_mismatch
FileNameWorkerPrivate-->>FileNameWorkerPrivate: skip candidateFileName
end
else keyword_not_pinyin
FileNameWorkerPrivate->>FileNameWorkerPrivate: appendSearchResult(candidateFileName)
end
end
FileNameWorkerPrivate-->>SearchUI: finalResults
SearchUI-->>User: display results
Class diagram for updated FileSearchUtils and FileNameWorkerPrivateclassDiagram
class FileSearchUtils {
+static QVariantHash tailerData(QFileInfo info)
+static QStringList buildDFMSearchFileTypes(QList_Group groupList)
+static bool isPinyin(QString str)
+static QString normalizePinyinKeyword(QString str)
+static bool matchSpecialChars(QString fileName, QString searchKeyword)
+static bool charsEquivalent(QChar ch1, QChar ch2)
+static bool hasWildcard(QString str)
}
class FileNameWorkerPrivate {
-SearchInfo m_searchInfo
-QStringList m_tmpSearchResults
-QMutex m_mutex
+bool appendSearchResult(QString fileName)
+SearchQuery createSearchQuery()
+SearchOptions createSearchOptions()
}
class SearchFactory {
+static SearchQuery createQuery(QString keyword, SearchQuery_Type type)
}
class SearchQuery {
<<enumeration>> Type
Type Simple
Type Wildcard
+Type queryType
}
class SearchInfo {
+QString keyword
+QStringList boolKeywords
+QStringList typeKeywords
}
FileNameWorkerPrivate --> FileSearchUtils : uses
FileNameWorkerPrivate --> SearchFactory : creates_queries
FileNameWorkerPrivate --> SearchInfo : reads
SearchFactory --> SearchQuery : creates
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Hey - I've left some high level feedback:
- In matchSpecialChars, digits from the search keyword are currently treated as special characters (using
!ch.isLetter()), but digits are explicitly excluded on the filename side (!ch.isLetter() && !ch.isDigit()), which will cause cases like"cs(1)"to fail unexpectedly; consider aligning the conditions so digits are consistently ignored in both places. - The logic to strip non-letter characters from a keyword is duplicated in isPinyin and normalizePinyinKeyword; consider refactoring to have isPinyin call normalizePinyinKeyword (or a shared helper) to avoid divergence in future changes.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- In matchSpecialChars, digits from the search keyword are currently treated as special characters (using `!ch.isLetter()`), but digits are explicitly excluded on the filename side (`!ch.isLetter() && !ch.isDigit()`), which will cause cases like `"cs(1)"` to fail unexpectedly; consider aligning the conditions so digits are consistently ignored in both places.
- The logic to strip non-letter characters from a keyword is duplicated in isPinyin and normalizePinyinKeyword; consider refactoring to have isPinyin call normalizePinyinKeyword (or a shared helper) to avoid divergence in future changes.Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
Fix the issue where global search matches special characters Log: Fix the issue where global search matches special characters
deepin pr auto review#。这段代码主要是为了增强文件名搜索功能,特别是针对拼音搜索和特殊字符匹配的改进。以下是对代码的详细审查意见: 1. 语法逻辑优点:
改进建议:
// 在 matchSpecialChars 函数开头添加
if (searchSpecialChars.contains(' ') || searchSpecialChars.contains(' ')) {
// 可以选择忽略空格或进行特殊处理
}
static const QMap<QChar, QChar> specialEquivalents = {
{'"', '"'}, // 双引号
{'\'', '\''}, // 单引号
{'`', '`'}, // 反引号
// 添加更多等价关系
};2. 代码质量优点:
改进建议:
QString FileSearchUtils::normalizePinyinKeyword(const QString &str)
{
QString result;
for (const QChar &ch : str) {
if (ch.isLetter()) {
result.append(ch);
}
}
return result;
}
bool FileSearchUtils::matchSpecialChars(const QString &fileName, const QString &searchKeyword)
{
// 提取搜索关键字中的特殊字符
QSet<QChar> searchSpecialChars;
for (const QChar &ch : searchKeyword) {
if (!ch.isLetter() && !ch.isDigit()) {
searchSpecialChars.insert(ch);
}
}
if (searchSpecialChars.isEmpty()) {
return true;
}
// 提取文件名中的特殊字符
QSet<QChar> fileSpecialChars;
QFileInfo fileInfo(fileName);
QString baseName = fileInfo.completeBaseName();
for (const QChar &ch : baseName) {
if (!ch.isLetter() && !ch.isDigit()) {
fileSpecialChars.insert(ch);
}
}
// 检查每个搜索特殊字符是否在文件特殊字符中找到等价字符
for (const QChar &searchChar : searchSpecialChars) {
bool found = false;
for (const QChar &fileChar : fileSpecialChars) {
if (charsEquivalent(searchChar, fileChar)) {
found = true;
break;
}
}
if (!found) {
qCDebug(logDaemon) << "Special char mismatch - File:" << fileName
<< "Search:" << searchKeyword
<< "Missing char:" << searchChar;
return false;
}
}
return true;
}3. 代码性能改进建议:
static QHash<QChar, QChar> createCharEquivalentMap()
{
QHash<QChar, QChar> map;
// 全角半角转换
for (ushort u = 0xFF01; u <= 0xFF5E; ++u) {
map.insert(QChar(u), QChar(u - 0xFEE0));
map.insert(QChar(u - 0xFEE0), QChar(u));
}
return map;
}
static QHash<QChar, QChar> charEquivalentMap = createCharEquivalentMap();
bool FileSearchUtils::charsEquivalent(const QChar &ch1, const QChar &ch2)
{
if (ch1 == ch2) {
return true;
}
return charEquivalentMap.value(ch1, QChar()) == ch2;
}
QString FileSearchUtils::normalizePinyinKeyword(const QString &str)
{
QString result = str;
for (int i = result.size() - 1; i >= 0; --i) {
if (!result.at(i).isLetter()) {
result.remove(i, 1);
}
}
return result;
}4. 代码安全改进建议:
bool FileSearchUtils::matchSpecialChars(const QString &fileName, const QString &searchKeyword)
{
if (fileName.isEmpty()) {
return false;
}
// 其余代码...
}
bool FileSearchUtils::charsEquivalent(const QChar &ch1, const QChar &ch2)
{
if (ch1 == ch2) {
return true;
}
ushort u1 = ch1.unicode();
ushort u2 = ch2.unicode();
if (u1 >= 0xFF01 && u1 <= 0xFF5E) {
ushort converted = u1 - 0xFEE0;
if (converted >= 0x0021 && converted <= 0x007E) { // 检查转换后的字符是否在有效范围内
if (QChar(converted) == ch2) {
return true;
}
}
}
if (u2 >= 0xFF01 && u2 <= 0xFF5E) {
ushort converted = u2 - 0xFEE0;
if (converted >= 0x0021 && converted <= 0x007E) { // 检查转换后的字符是否在有效范围内
if (QChar(converted) == ch1) {
return true;
}
}
}
return false;
}
QString FileSearchUtils::normalizePinyinKeyword(const QString &str)
{
if (str.size() > 1000) { // 设置合理的上限
qCWarning(logDaemon) << "Keyword too long, truncating:" << str.size();
return QString();
}
QString result;
result.reserve(str.size()); // 预分配内存
for (const QChar &ch : str) {
if (ch.isLetter()) {
result.append(ch);
}
}
return result;
}总结这段代码整体质量良好,实现了拼音搜索和特殊字符匹配的功能。主要改进方向包括:
建议在正式合并前,进行充分的性能测试,特别是在处理大量文件和长字符串时的性能表现。 |
Johnson-zs
left a comment
There was a problem hiding this comment.
nh! 搜不到应该是因为dfm-search库在处理 !时,被当做Lucene语法处理了。nh! 搜不到应该是因为dfm-search库在处理 !时,被当做Lucene语法处理了
|
resolved by linuxdeepin/util-dfm#252 |
Fix the issue where global search matches special characters
Log: Fix the issue where global search matches special characters
Summary by Sourcery
Improve pinyin-based filename search to correctly handle special characters in keywords and filenames.
Bug Fixes:
Enhancements:
Tests: