【问题标题】:Looking for simple yet powerful windows wildcards (`*, ?`) matching implementation寻找简单而强大的 windows 通配符(`*, ?`)匹配实现
【发布时间】:2012-02-09 04:18:32
【问题描述】:

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

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

需要一个快乐的媒介。

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

  • 文件应该不在存储库的索引中(所以我正在对照存储在索引中的路径检查文件的路径)
  • .gitignore 中的模式数量可能很大;
  • 要检查的文件数量也可能很大。

【问题讨论】:

  • 非常模糊。发布一些具有所需输出的输入。
  • @Henk,大多数 Windows 用户都知道是什么意思,* 任意数量的字符,?只是 1 个未知字符... ?blah*.txt 将匹配任何内容与 blah 之前的字符、blah 之后的任意数量的字符并以 .txt 结尾
  • @HenkHolterman,我正在解析 .gitignore 文件,在我的库中,我需要实现与原始 Git 提供的相同的行为。
  • @seldon,谢谢!它非常接近我实际搜索的内容!

标签: c# .net regex wildcard


【解决方案1】:

转换 * 和 ?正则表达式很容易。
为了 ?更换 ”?”与“。{1}” 而对于 * 将“*”替换为“.+?”

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

编辑: boolean PathMatchSpec(input, pattern) 将完成这项工作。

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

【讨论】:

  • 是的,这很容易,但是有没有其他方法可以不将一种模式转换为另一种模式?
  • 您还需要对正则表达式中具有特殊含义的字符进行转义。
  • 是的,这就是我询问不同方法的原因。
  • PathMatchSpec 的编辑答案
  • 真的很酷的功能!但我的库往往是跨平台的,并且使用纯 .NET...
【解决方案2】:

Windows 通配符?* 在正则表达式中的等效项只是..*


[编辑] 鉴于您的新编辑(说明您正在寻找实际文件),我将完全跳过翻译并让 .Net 使用Directory.GetFiles().

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

【讨论】:

  • 就我个人而言,我不喜欢翻译成正则表达式的想法。因为很多东西也需要翻译。例如点、大括号,它们需要被转义。而且我不能保证用户在输入通配符时会准确无误。这使方法变得复杂。
  • 编写自己的模式匹配肯定比翻译成正则表达式更复杂。
  • @Alexey:见Regex.Escape()
  • @BlueRaja:谢谢,这是我一直在寻找的方式!
  • @CodesInChaos 在这种情况下并非如此,请查看我对另一个问题的回答:stackoverflow.com/a/16488364/119561
【解决方案3】:

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

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

【讨论】:

    【解决方案4】:

    要获得包含所有极端情况的精确匹配,请使用

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

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

    换句话说,我认为你应该保持你的模式干燥,直到满足文件系统的时间。

    【讨论】:

    • 这对我来说几乎没用,因为我按照你指出的方式获取文件夹中的所有文件,而不是检查有多少文件从 Git 索引中出来。在留下的文件中,我搜索了那些与.gitignore 中的模式集不匹配的文件。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-02-10
    • 1970-01-01
    • 2018-06-21
    • 2016-03-05
    • 1970-01-01
    • 1970-01-01
    • 2020-12-18
    相关资源
    最近更新 更多