与通配符匹配的文件名
我需要实现类似我自己的文件系统的东西。一个操作是 FindFirstFile。我需要检查调用者是否传递了类似 .、sample*.cpp 等内容。我的“文件系统”实现提供“文件名”列表作为 char* 数组。
Windows有没有函数或源代码实现这种文件名匹配?
I need to implement something like my own file system. One operation would be the FindFirstFile. I need to check, if the caller passed something like ., sample*.cpp or so. My "file system" implementation provides the list of "files names" as a array of char*.
Is there any Windows function or any source code that implements this file name matching?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(10)
对于使用“*”和“?”的通配符名称匹配试试这个(如果你想避免提升,请使用 std::tr1::regex):
For wildcard name matching using '*' and '?' try this (if you want to avoid boost, use std::tr1::regex):
周围有很多这样的功能。这是各种实现的目录,分为递归和非递归,如果
您不喜欢那里的许可(或者链接有问题等),这里有一种可能的匹配算法实现,该算法至少非常接近 Windows 使用的算法:
由于讨论了某些算法的复杂性其他答案,我会注意到我相信这具有 O(NM) 复杂性和 O(M) 存储使用(其中 N 是目标字符串的大小,M 是模式的大小)。
使用 @masterxilo 的测试对:
...这在我的机器上大约 3 微秒内找到了匹配项。这比典型模式慢很多——我的大多数其他测试在这台特定机器上运行大约 300 纳秒左右。
同时,@masterxilo 的代码在同一台机器上运行大约需要 11 微秒,因此速度仍然快了大约 3 到 4 倍(更不用说更小、更简单了)。
There are quite a few such functions around. Here's a directory of various implementations, sorted into recursive and non-recursive, etc.
In case you don't like the licensing there (or have trouble with the link, etc.) here's one possible implementation of a matching algorithm that at least closely approximates what Windows uses:
Since there was a discussion of complexity of some of the other answers, I'll note that I believe this has O(NM) complexity and O(M) storage use (where N is the size of the target string, and M is the size of the pattern).
With @masterxilo's test pair:
...this finds a match in approximately 3 microseconds on my machine. That is a lot slower than a typical pattern--most of my other tests run in about 300 nanoseconds or so on this particular machine.
At the same time, @masterxilo's code takes approximately 11 microseconds to run on the same machine, so this is still around 3 to 4 times faster (not to mention being somewhat smaller and simpler).
查看 POSIX 函数
fnmatch
、glob
和wordexp
。Have a look at the POSIX functions
fnmatch
,glob
, andwordexp
.这是我的尝试。
它是“C++”,但我故意保持它几乎完全与 C 兼容。
为了将其转换为 C,您所需要做的就是删除
template
部分并将Pattern
和Text
更改为类似字符常量*
。当然,您可以随意以任何您想要的方式使用该代码。 :)
Here's my attempt at this.
It's "C++", but I've deliberately kept it almost completely C-compatible.
All you need to do in order to convert it to C is to remove the
template
section and changePattern
andText
to something likechar const *
.Of course, feel free to use the code in any way you want. :)
Mehrdad 提供的解决方案具有指数级的运行时间,因为它使用回溯。花了一秒钟才弄清楚
"*a*??????*a*?????????a??????????????? ?”,“啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊aaa"
是一个匹配。此外,也无法将字符串与“*”或“?”进行匹配。在其中。这是我提出的 O(nm) 实现,其内存使用量为 O(n),其中 n 是表达式的长度,m 是字符串的长度。它还支持转义 ?、* 和 \。
这使用了虚拟机方法。有关高效正则表达式解析的更多信息,请参阅 http://swtch.com/~rsc/regexp/ 。
The solution Mehrdad provided has exponential running time because it uses backtracking. It takes it like a second to figure out that
"*a*??????*a*?????????a???????????????", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
is a match. Also there's no way to match a string with '*' or '?' in it.Here's an O(nm) implementation I came up with which has O(n) memory usage, where n is the length of the expression, m the length of the string. It also supports escaping ?, * and \.
This uses a virtual machine approach. See http://swtch.com/~rsc/regexp/ for more on efficitent regular expression parsing.
这是一个无依赖的可移植 C++ 版本:
Here is a dependency free portable C++ version:
PathMatchSpec。尽管它受到
MAX_PATH
限制(即可接受不超过 260 个字符)。你最好实现自己的匹配器;这不是很多代码。PathMatchSpec. Though it suffers from the
MAX_PATH
limitation (i.e. can accept no more than 260 characters). You may be better off implementing your own matcher; it's not a lot of code.这与 @nabulke 的答案几乎相同,使用 C++11 而不是 Boost (所以如果您喜欢这个答案,请务必给这个答案点赞):
This is pretty much the same as @nabulke's answer, using C++11 instead of Boost (so be sure to upvote that one too if you like this answer):
您也可以尝试我的通配符匹配库: Wildest card
它是:
示例:
Also you can try my wildcard matching library: Wildest card
It is:
Example:
这是一个高效的方法,它对字符串进行一次遍历,并在不需要的地方跳过比较(模式中的最后一个字符恰好是“*”,或者如果“*”之前的字符没有相同的字符)索引匹配)。它也不会通过使用指针来复制任何字符串,并且不会浪费任何 CPU 周期来使用 strlen()、sizeof()、.length() 或 .size() 获取字符串长度
Here's an efficient one that does a single traverse of the string, and skips comparisons where they're not needed (the last character in pattern happens to be a '*' or if a character before a '*' doesn't have the same index match). It also doesn't copy any strings by making use of pointers and doesn't waste any CPU cycles on getting the string length with strlen(), sizeof(), .length(), or .size()