在输入上我有字符串,可以是普通路径字符串(例如/home/user/1.txt
)或glob模式(例如/home/user/*.txt
)。
接下来我想获得匹配数组,如果string是glob模式,并且在string只是普通路径的情况下我想获得具有单个元素的数组 - 这个路径。
所以我应该检查字符串是否包含未转义的glob符号,如果是,则调用Pathname.glob()
来获取匹配,否则只返回带有此字符串的数组。
如何检查字符串是否为glob模式?
更新
我在实施homebrew cask glob pattern support for zap stanza时遇到了这个问题。 我使用的解决方案是进行一些重构,以避免需要检查字符串是否为glob模式。
答案 0 :(得分:1)
接下来我想获得匹配数组,如果string是glob模式,并且在string只是普通路径的情况下我想获得具有单个元素的数组 - 这个路径。
它们都是有效的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字符,但这会很快变得复杂容易出错。它需要knowing how glob
works in detail并记住要检查引用和转义。 foo*
有一个glob模式。 foo\*
没有。 foo[123]
。 foo\[123]
没有。而且我不确定foo[123\]
正在做什么,我认为它算作一个非终止集。
通常,您希望避免编写必须重现另一段代码的内部工作的代码。如果有Pathname.has_glob_chars
你可以使用它,但没有这样的东西。
Pathname.glob
使用File.fnmatch
进行通配,您可以在不触及文件系统的情况下使用它。你可能能够用它来提出一些东西,但我无法使它发挥作用。我想也许只有文字路径会匹配自己,但foo*
会失败。
相反,检查它是否存在。
Pathname.new(path).exist?
如果它存在,它是真实文件的真实路径。如果它不存在,它可能是一条真正的路径,或者它可能是一个全局。这可能已经足够了。
您还可以查看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