我有一个文件名列表,我想在上面实现Dir::glob。
我认为这很容易,因为有File::fnmatch看起来像是正确的工具。然而,在某些情况下,这两种方法的行为不同:
# Given a directory layout like this:
# +
# |-- file
# |-+ folder
# | |-- file
# gives ['file','folder/file']
Dir.glob('**/file')
# gives ['folder/file']
['file','folder','folder/file'].select{|n| File.fnmatch?('**/file', n) }
加上斜杠解决了这个问题,但又引入了另一个问题:
# gives ['file,'folder/file']
['file','folder','folder/file'].select{|n| File.fnmatch?('**/file','/'+n) }
# gives an empty array, but should give 'file' and 'folder' like Dir.glob does.
['file','folder','folder/file'].select{|n| File.fnmatch?('f*','/'+n) }
有人已经解决了这个问题,还是我必须做一些Regexp魔法(tm)?
你需要点一个FNM_PATHNAME
标志
> ['file','folder','folder/file'].select{|n| File.fnmatch?('**/file', n, File::FNM_PATHNAME) }
=> ["file", "folder/file"]
> ['file','folder','folder/file'].select{|n| File.fnmatch?('f*',n, File::FNM_PATHNAME) }
=> ["file", "folder"]
尝试通过File::FNM_PATHNAME
标志,
['file','folder','folder/file'].select{|n| File.fnmatch?('**/file', n,File::FNM_PATHNAME) }
=> ["file", "folder/file"]
不确定这是否适用于所有情况,但**文件(没有斜杠)似乎匹配您的测试用例:
['file', 'folder', 'folder/file'].select {|n| File.fnmatch?('**file', n) }