接下來,我想獲得匹配數組,如果字符串是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")
=> []
這是一個很好的方式來提前規範和驗證您的數據,所以程序的其餘部分不必。
如果你真的想弄清楚,如果事情是文本路徑或水珠,你可以嘗試掃描任何特殊字符水珠,但很快變得複雜而且容易出錯。它需要knowing how glob
works in detail並記住檢查報價和轉義。 foo*
有一個glob模式。 foo\*
沒有。 foo[123]
呢。 foo\[123]
沒有。我不確定foo[123\]
在做什麼,我認爲它算作一個未終止的集合。
一般而言,您希望避免編寫必須重現另一段代碼內部工作的代碼。如果有一個Pathname.has_glob_chars
你可以使用它,但沒有這樣的事情。
Pathname.glob
使用File.fnmatch
做globbing,你可以使用它,而無需觸摸文件系統。你可能會想出一些使用它的東西,但我無法使它工作。我認爲也許只有一個文字路徑纔會匹配,但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
是的,普通路徑也是有效的glob模式(我們稱之爲微不足道的)。但是glob模式不是一個有效的路徑。我想知道什麼時候處理不平凡的模式,何時處理簡單的路徑。 – mixel
@mixel爲什麼?您想要將路徑/全局縮減爲路徑列表。 'Pathname.glob'這樣做。弄清楚它是否是一個文字路徑只會增加代碼和時間以及複雜性和錯誤。 – Schwern
我知道,但是需要很長時間才能解釋爲什麼我需要這個,所以我希望有一些標準的方法來檢查字符串是否在Ruby中不平凡的glob模式。如果沒有簡單的方法,除了正則表達式匹配,那麼好的,我會試圖找出它或甚至可能重構我的項目,以消除需要檢查。 – mixel