检查字符串是否为全局模式

3

输入的字符串可以是纯路径字符串(例如/home/user/1.txt)或通配符模式(例如/home/user/*.txt)。

如果字符串是通配符模式,则需要获取匹配的数组;如果字符串只是纯路径,则需要获取一个只包含此路径的数组。

因此,我需要检查字符串是否包含未转义的通配符符号,如果包含,则调用Pathname.glob()来获取匹配项,否则只需返回包含此字符串的数组。

如何检查字符串是否为通配符模式?

更新

我在实现homebrew cask glob pattern support for zap stanza时遇到了这个问题。我使用的解决方案是进行一些小的重构,以避免需要检查字符串是否为通配符模式。

1个回答

1
如果字符串是glob模式,我希望获得匹配数组;如果字符串只是一个普通的路径,则希望获得只有一个元素-该路径的数组。它们都是有效的glob模式。其中一个包含通配符,另一个不包含。将它们都通过Pathname.glob()运行,您将始终收到一个数组。奖励是,它会检查是否匹配任何内容。
$ irb
2.3.3 :001 > require "pathname"
 => true 
2.3.3 :002 > Pathname.glob("test.data")
 => [#<Pathname:test.data>] 
2.3.3 :003 > Pathname.glob("test.*")
 => [#<Pathname:test.asm>, #<Pathname:test.c>, #<Pathname:test.cpp>, #<Pathname:test.csv>, #<Pathname:test.data>, #<Pathname:test.dSYM>, #<Pathname:test.html>, #<Pathname:test.out>, #<Pathname:test.php>, #<Pathname:test.pl>, #<Pathname:test.py>, #<Pathname:test.rb>, #<Pathname:test.s>, #<Pathname:test.sh>] 
2.3.3 :004 > Pathname.glob("doesnotexist")
 => []

这是一种很好的方式,可以在程序的早期对数据进行规范化和验证,以便后续程序不必再进行此操作。
如果您真的想确定某个内容是字面路径还是通配符,可以尝试扫描任何特殊的通配符字符,但这很容易变得复杂和容易出错。它需要了解详细了解glob的工作原理并记住检查引用和转义。 foo* 是一个通配符模式。 foo\* 不是。 foo[123] 是。 foo\[123] 不是。我不确定 foo[123\] 在做什么,我认为它算作未终止的集合。
一般来说,您希望避免编写必须重现另一个代码片段内部工作方式的代码。如果有一个Pathname.has_glob_chars,您可以使用它,但实际上并没有这样的东西。

Pathname.glob 使用 File.fnmatch 进行模式匹配,你可以使用它而不接触文件系统。你可能可以通过使用它来想出一些方法,但我无法使其工作。我以为只有字面路径才能匹配自己,但 foo* 打破了这个假设。

相反,检查它是否存在。

Pathname.new(path).exist?

如果存在,它是指向真实文件的真实路径。如果不存在,它可能是一个真实路径,也可能是一个glob。这应该已经足够了。
您还可以通过查看Pathname.glob(path)是否返回与原始路径匹配的单个元素来进行检查。注意,在匹配路径时,使用cleanpath对两侧进行规范化非常重要。
paths = Pathname.glob(path)

if paths.size == 1 && paths[0].cleanpath == Pathname.new(path).cleanpath
    puts "#{path} is a literal path"
elsif paths.size == 0
    puts "#{path} matched nothing"
else
    puts "#{path} was a glob"
end

是的,简单路径也是有效的通配符模式(我们称之为微不足道的)。但通配符模式不是有效的路径。我想知道何时处理非微不足道的模式,何时处理普通路径。 - undefined
@mixel 为什么呢?你想将路径/通配符减少到一个路径列表。Pathname.glob 就可以做到这一点。判断它是否是字面路径只会增加代码、时间、复杂性和错误。 - undefined
我知道,但是解释为什么我需要这个会花很长时间,所以我希望有一种标准的方法来检查字符串是否是Ruby中的非平凡通配符模式。如果除了正则表达式匹配之外没有简单的方法,那么好吧,我会尝试弄清楚,或者甚至重构我的项目以消除检查的需要。 - undefined
1
@mixel 你遇到了一个XY问题,而且可能有更好的解决方法。你应该询问你试图解决的真正问题,即使很难解释,在一个新的问题中提出来。试图确定路径是否包含通配符的代码将更难维护。 - undefined
1
重构似乎是最好的解决方案。您不应该检查通配符是简单还是复杂,您的代码应该在任何情况下都能正常工作。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接