检查字符串是否为 glob 模式
Check if string is a glob pattern
在输入中,我的字符串可以是普通路径字符串(例如 /home/user/1.txt
)或 glob 模式(例如 /home/user/*.txt
)。
接下来,如果字符串是 glob 模式,我想获取匹配项数组,如果字符串只是普通路径,我想获取包含单个元素的数组 - 此路径。
所以我应该以某种方式检查字符串是否包含未转义的 glob 符号,如果包含则调用 Pathname.glob()
以获取匹配项,否则只需 return 数组与此字符串。
如何检查字符串是否为 glob 模式?
更新
我在实施 homebrew cask glob pattern support for zap stanza 时遇到了这个问题。
我使用的解决方案是进行一些重构以避免需要检查字符串是否为 glob 模式。
Next I want to get array of matches if string is glob pattern and in case when string is just plain path I want to get array with single element - this path.
它们都是有效的 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,您可以尝试扫描任何特殊的 glob字符,但这很快就会变得复杂且容易出错。它需要 knowing how glob
works in detail 并记住检查引号和转义。 foo*
有一个 glob 模式。 foo\*
没有。 foo[123]
确实如此。 foo\[123]
没有。而且我不确定 foo[123\]
在做什么,我认为它算作 non-terminated 集。
一般来说,您希望避免编写必须重现另一段代码的内部工作原理的代码。如果有 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
在输入中,我的字符串可以是普通路径字符串(例如 /home/user/1.txt
)或 glob 模式(例如 /home/user/*.txt
)。
接下来,如果字符串是 glob 模式,我想获取匹配项数组,如果字符串只是普通路径,我想获取包含单个元素的数组 - 此路径。
所以我应该以某种方式检查字符串是否包含未转义的 glob 符号,如果包含则调用 Pathname.glob()
以获取匹配项,否则只需 return 数组与此字符串。
如何检查字符串是否为 glob 模式?
更新
我在实施 homebrew cask glob pattern support for zap stanza 时遇到了这个问题。 我使用的解决方案是进行一些重构以避免需要检查字符串是否为 glob 模式。
Next I want to get array of matches if string is glob pattern and in case when string is just plain path I want to get array with single element - this path.
它们都是有效的 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,您可以尝试扫描任何特殊的 glob字符,但这很快就会变得复杂且容易出错。它需要 knowing how glob
works in detail 并记住检查引号和转义。 foo*
有一个 glob 模式。 foo\*
没有。 foo[123]
确实如此。 foo\[123]
没有。而且我不确定 foo[123\]
在做什么,我认为它算作 non-terminated 集。
一般来说,您希望避免编写必须重现另一段代码的内部工作原理的代码。如果有 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