寻找简单但功能强大的Windows通配符(`*,?`)匹配实现

时间:2022-09-01 23:09:16

I'm looking for simple and powerful way to implement Windows flavoured * and ? wildcards matching in strings.

我正在寻找简单而强大的方法来实现Windows风格的*和?字符串中匹配的通配符。

BeginsWith(), EndsWith() too simple to cover all cases, while translating wildcards expressions to regex'es will look to complex and I'm not sure about performance.

BeginsWith(),EndsWith()过于简单,无法涵盖所有​​情况,而将通配符表达式转换为正则表达式看起来很复杂,我不确定性能。

A happy medium wanted.

想要一个快乐的媒体。

EDIT: I'm trying to parse .gitignore file and match the same files, as Git does. This means:

编辑:我正在尝试解析.gitignore文件并匹配相同的文件,就像Git一样。这意味着:

  • File should be out of repository's index (so I'm checking file's path against one stored in index)
  • 文件应该在存储库的索引之外(所以我正在检查文件的路径与存储在索引中的路径)

  • Number of patterns in .gitignore can be large;
  • .gitignore中的模式数量可能很大;

  • Number of files to check might also be large.
  • 要检查的文件数也可能很大。

4 个解决方案

#1


4  

The equivalents of the Windows wildcards ? and * in regex are just . and .*.

Windows通配符的等价物?和正则表达式中的*是公正的。和。*。


[Edit] Given your new edit (stating that you're looking for actual files), I would skip the translation altogether and let .Net do the searching using Directory.GetFiles().

[编辑]鉴于你的新编辑(说明你正在寻找实际文件),我会完全跳过翻译,让.Net使用Directory.GetFiles()进行搜索。

(note that, for some reason, passing a ? into Directory.GetFiles() matches "zero or one characters," whereas in Windows it always matches exactly one character)

(请注意,由于某种原因,将?传递到Directory.GetFiles()匹配“零个或一个字符”,而在Windows中它总是匹配一个字符)

#2


2  

To get an exact match including all corner-cases, use

要获得包括所有角落情况的完全匹配,请使用

System.IO.Directory.GetFiles(myPath, myPattern)

You may have to create some tempfiles form your targetstrings first.

您可能必须首先在您的目标字符串中创建一些临时文件。

In other words, I think you should keep your patterns dry until it's time to meet the filesytem.

换句话说,我认为你应该保持模式干燥,直到遇到文件系统为止。

#3


1  

You should go with regex based approach unless your data volume is humungous or you have data-points to say regex will severely impact performance.

您应该使用基于正则表达式的方法,除非您的数据量很大或者您有数据点表示正则表达式会严重影响性能。

If that is the case, any other solution will also likely affect the performance and you will probably need to hand-roll something.

如果是这种情况,任何其他解决方案也可能会影响性能,您可能需要手动滚动。

#4


1  

Converting * and ? to regex is quite easy.
For ? replace the "?" with ".{1}" and for * replace the "*" with ".+?"

转换*和?正则表达式很容易。为了?更换 ”?”用“。{1}”和*代替“*”替换为“。+?”

That should get you the same behaviour as wildcard matching on windows.

这应该会让你获得与Windows上的通配符匹配相同的行为。

EDIT: boolean PathMatchSpec(input, pattern) will do the job.

编辑:布尔值PathMatchSpec(输入,模式)将完成这项工作。

Private Declare Auto Function PathMatchSpec Lib "shlwapi" (ByVal pszFileParam As String, ByVal pszSpec As String) As Boolean

#1


4  

The equivalents of the Windows wildcards ? and * in regex are just . and .*.

Windows通配符的等价物?和正则表达式中的*是公正的。和。*。


[Edit] Given your new edit (stating that you're looking for actual files), I would skip the translation altogether and let .Net do the searching using Directory.GetFiles().

[编辑]鉴于你的新编辑(说明你正在寻找实际文件),我会完全跳过翻译,让.Net使用Directory.GetFiles()进行搜索。

(note that, for some reason, passing a ? into Directory.GetFiles() matches "zero or one characters," whereas in Windows it always matches exactly one character)

(请注意,由于某种原因,将?传递到Directory.GetFiles()匹配“零个或一个字符”,而在Windows中它总是匹配一个字符)

#2


2  

To get an exact match including all corner-cases, use

要获得包括所有角落情况的完全匹配,请使用

System.IO.Directory.GetFiles(myPath, myPattern)

You may have to create some tempfiles form your targetstrings first.

您可能必须首先在您的目标字符串中创建一些临时文件。

In other words, I think you should keep your patterns dry until it's time to meet the filesytem.

换句话说,我认为你应该保持模式干燥,直到遇到文件系统为止。

#3


1  

You should go with regex based approach unless your data volume is humungous or you have data-points to say regex will severely impact performance.

您应该使用基于正则表达式的方法,除非您的数据量很大或者您有数据点表示正则表达式会严重影响性能。

If that is the case, any other solution will also likely affect the performance and you will probably need to hand-roll something.

如果是这种情况,任何其他解决方案也可能会影响性能,您可能需要手动滚动。

#4


1  

Converting * and ? to regex is quite easy.
For ? replace the "?" with ".{1}" and for * replace the "*" with ".+?"

转换*和?正则表达式很容易。为了?更换 ”?”用“。{1}”和*代替“*”替换为“。+?”

That should get you the same behaviour as wildcard matching on windows.

这应该会让你获得与Windows上的通配符匹配相同的行为。

EDIT: boolean PathMatchSpec(input, pattern) will do the job.

编辑:布尔值PathMatchSpec(输入,模式)将完成这项工作。

Private Declare Auto Function PathMatchSpec Lib "shlwapi" (ByVal pszFileParam As String, ByVal pszSpec As String) As Boolean