【问题标题】:Easiest way to convert "a/b/c" to ["a/b/c", "a/b", "a"]将 "a/b/c" 转换为 ["a/b/c", "a/b", "a"] 的最简单方法
【发布时间】:2010-02-13 09:09:21
【问题描述】:

在 Ruby 中,我想将斜杠分隔的字符串(例如“foo/bar/baz”)转换为 [“foo/bar/baz”、“foo/bar”、“foo”]。我已经有了几行长的解决方案;我正在寻找一个优雅的单线。它还需要适用于任意数量的段(0 及以上)。

【问题讨论】:

  • 你知道FileUtils.mkdir_p,对吧?

标签: ruby regex


【解决方案1】:
"foo/bar/baz".enum_for(:scan, %r{/|$}).map {Regexp.last_match.pre_match}

【讨论】:

  • 哇。没有所有括号,这几乎是 lisp。
  • 好!更简单的代码 "foo/bar/baz".enum_for(:scan, %r{/|$}).map {$`}
【解决方案2】:

最高投票的答案有效,但这里有一个稍微短一些的方法,我认为对于那些不熟悉那里使用的所有功能的人来说,它会更具可读性:

a=[]; s.scan(/\/|$/){a << $`}

结果存储在a:

> s = 'abc/def/ghi'
> a=[]; s.scan(/\/|$/){a << $`}
> a
["abc", "abc/def", "abc/def/ghi"]

如果顺序很重要,可以反转数组或者使用unshift代替&lt;&lt;

感谢 dkubb,感谢 OP 对此答案的改进。

【讨论】:

  • 在 ruby​​ 1.8.7 上,结果只有 #=> "abc/def/ghi" 而不是答案中指定的数组
  • @nas:返回值将是任何版本的 ruby​​ 中的字符串。请求的数组将位于a 变量中。如果您知道这一点并且只是在吹毛求疵,请随时忽略我的评论。
  • 您可以通过执行以下操作进一步简化块中的代码:a=[]; 'abc/def/ghi'.scan(/\/|$/){a
  • 我接受这一点,但需要注意的是,使用 unshift 将消除对反向的需要:)
  • @Yehuda Katz:使用 unshift 这将变为 O(n^2) 而不是 O(n) (我假设扫描可以使用给定的正则表达式线性遍历字符串),所以使用反向应该更有效。
【解决方案3】:

没有选择的答案那么有效,并且在给定一个空字符串时给出[],而不是[""],但它是一个真正的单行:P

s.split('/').inject([]) { |a,d| a.unshift( [a.first,d].compact.join('/') ) }

【讨论】:

    【解决方案4】:
    ->(l,s,z){
        ( t = s[/#{z}.[^\/]*/] ) && [l[l,s,t], t]
    }.tap{ |l|
        break l[l,'a/b/c','']
    }.flatten.compact
    

    【讨论】: