使用std::regex_search实现Windows文件搜索的错误排查与修复
问题排查与修复方案
你的问题出在正则表达式的匹配逻辑上——当前的正则只是检查文件名中是否包含.txt子串,而不是要求文件名以.txt结尾,所以像d.txt.lnk这种包含.txt的文件名会被错误匹配。下面是具体的修复步骤和优化建议:
1. 核心修复:修正通配符转正则的逻辑
你的GetPattern函数应该把Windows通配符(比如*.txt)转换成锚定整个文件名的正则表达式,确保只有完全符合后缀规则的文件才会被匹配。
比如,把*.txt转换成:
std::wregex(L"^.*\\.txt$")
^:匹配字符串的开始.*:匹配任意数量的任意字符(对应通配符*)\\.:转义.(因为正则里.是任意字符,需要转义成字面意义的点)$:匹配字符串的结束
修改后的GetPattern示例:
std::wregex GetPattern(const CString& searchString) { // 把通配符*转成.*,同时转义正则特殊字符 std::wstring pattern = searchString.GetString(); // 转义.为\. size_t pos = 0; while ((pos = pattern.find(L'.', pos)) != std::wstring::npos) { pattern.replace(pos, 1, L"\\."); pos += 2; } // 把*转成.* pos = 0; while ((pos = pattern.find(L'*', pos)) != std::wstring::npos) { pattern.replace(pos, 1, L".*"); pos += 2; } // 添加首尾锚点 pattern = L"^" + pattern + L"$"; return std::wregex(pattern); }
2. 代码逻辑优化
除了正则问题,你的代码还有几个可以优化的地方:
(1)提前过滤.和..目录
在处理每个文件/目录前,先排除.和..,避免无效的正则匹配和递归:
do { std::wstring fileName(findData.cFileName); // 先跳过.和.. if (fileName == L"." || fileName == L"..") { continue; } // 匹配文件 if (std::regex_search(fileName, searchPattern)) { std::wcout << L"找到文件:" << path << L"\\" << fileName << std::endl; // 这里可以把结果存入result集合 } // 递归处理子目录 if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { CString newPath = path + L"\\" + fileName.c_str(); RecursiveSearch(newPath, searchPattern); } } while (FindNextFile(fileHandle, &findData));
(2)修复资源泄漏
记得在循环结束后关闭FindFirstFile返回的句柄,避免资源泄漏:
// 循环结束后关闭句柄 if (fileHandle != INVALID_HANDLE_VALUE) { FindClose(fileHandle); }
(3)错误处理优化
如果FindFirstFile返回INVALID_HANDLE_VALUE,应该直接跳出循环,而不是继续:
fileHandle = FindFirstFile(newPath, &findData); if (fileHandle == INVALID_HANDLE_VALUE) { // 可以输出错误信息,比如调用GetLastError()查看具体原因 return result; }
3. 测试验证
修复后,搜索*.txt时:
- 正确匹配:
test.txt、my.file.txt - 错误匹配:
d.txt.lnk、txt.file、notxt会被排除
这样就能得到符合预期的搜索结果了。
内容的提问来源于stack exchange,提问作者asdadsasdwe
相关产品推荐
相关产品推荐

