通过Ruby stdlib从路径中提取规范化/规范化目录名?

通过Ruby stdlib从路径中提取规范化/规范化目录名?,ruby,Ruby,假设您有一个路径字符串,该字符串可以是: Foo/Bar/Baz.txt Foo/Bar/ Foo/Bar 在每种情况下,您都希望使用Ruby标准库中的方法隔离字符串中的目录层次结构,从而得到值Foo/Bar。有没有一种方法可以做到这一点?不幸的是,Path#cleanpath和API中的其他方法保留了字符串中的尾部斜杠 是否有一个单一方法或短方法链的行为如下 File.directory?(路径)?path.chomp(“/”):File.split(path)[0] 通过正则表达式实现所

假设您有一个路径字符串,该字符串可以是:

  • Foo/Bar/Baz.txt
  • Foo/Bar/
  • Foo/Bar
在每种情况下,您都希望使用Ruby标准库中的方法隔离字符串中的目录层次结构,从而得到值
Foo/Bar
。有没有一种方法可以做到这一点?不幸的是,
Path#cleanpath
和API中的其他方法保留了字符串中的尾部斜杠

是否有一个单一方法或短方法链的行为如下

File.directory?(路径)?path.chomp(“/”):File.split(path)[0]


通过正则表达式实现所需行为的另一个例子是。

不,在Ruby API中似乎没有明确的方法来实现这一点。另一种方法是使用正则表达式。

不太确定我是否理解您的问题,但如果您想拆分目录和文件,可以这样做:

path = "/etc/hosts" ; File.directory?(path) &&  [ File.dirname(path) + "/" +  
File.basename(path), nil ]  ||  [ File.dirname(path),  File.basename(path) ]
=> ["/etc", "hosts"]

path = "/var/lib" ; File.directory?(path) &&  [ File.dirname(path) + "/" +  
File.basename(path), nil ]  ||  [ File.dirname(path),  File.basename(path) ]
=> ["/var/lib", nil]
但请注意,此解决方案仅适用于现有文件的域。如果您计划创建路径,则不可能知道答案中的
Bar
应放在何处(在上面的示例中,它将被视为一个文件)

请注意,答案应该是标准化的:

path = "//etc//hosts" ; File.directory?(path) &&  [ File.dirname(path) + "/" +  
File.basename(path), nil ]  ||  [ File.dirname(path),  File.basename(path) ]
=> ["/etc", "hosts"]
然而,
dirname
的规范化是有限的/有缺陷的(在我看来):

解析是困难的,只要有可能避免它,您肯定会节省时间。与其规范化文件路径,我宁愿信任它们的
inode
编号(同样,仅对现有文件域有效):


我没听清你真正的问题!:-)我添加了一个片段来说明这种行为。第二句和第三句清楚地说明了这个问题。
path = "/./etc//hosts" ; File.directory?(path) &&  [ File.dirname(path) + "/" 
+  File.basename(path), nil ]  ||  [ File.dirname(path),  File.basename(path) ]
=> ["/./etc", "hosts"]
[ File.stat("/etc/hosts").ino , File.stat("/./etc/hosts").ino ]
=> [1309513, 1309513]