在以冒号开头的单词上拆分字符串

时间:2016-03-25 09:57:03

标签: ruby string split

我正在尝试创建一个方法,该方法在哈希中获取密钥的一部分,并将其与输入中的值进行比较。关键看起来像这样:

policy :allow ,:denied ,:closed

我正在尝试将此密钥拆分为仅allowdeniedclosed,以便我可以将这些值与我输入的值进行比较。

我现在有这个:

key.split(/: */)

这给了我:

policy closed, allow, denied

如何删除第一个单词policy,

4 个答案:

答案 0 :(得分:1)

虽然我喜欢使用正则表达式,但它可能令人生畏。 所以我总是试图寻找替代方案。

这是我的版本(简单的正则表达式):

str = 'policy :allow, :denied, :closed'

policies1 = str.scan /(?<=:)\w+/
policies2 = str.split(/, :|:/)[1..-1]

#=> ["allow", "denied", "closed"]

require 'benchmark'


n = 5000000
Benchmark.bmbm do |x|
  x.report("scan")   { for i in 1..n;  policies = str.scan /(?<=:)\w+/ ; end }
  x.report("split")  { for i in 1..n;  policies = str.split(/, :|:/)[1..-1] ; end }
end

使用此结果

Rehearsal -----------------------------------------
scan   15.670000   0.050000  15.720000 ( 15.725932)
split  13.050000   0.110000  13.160000 ( 13.160543)
------------------------------- total: 28.880000sec

            user     system      total        real
scan   16.130000   0.080000  16.210000 ( 16.217341)
split  12.980000   0.100000  13.080000 ( 13.095190)

答案 1 :(得分:1)

我认为没有必要使用正则表达式:

str = 'policy :allow ,:denied ,:closed'
str.tr(':,', '').split[1..-1] # => ["allow", "denied", "closed"]

这实际上是一个删除垃圾然后拆分空白并抓住某些字段的问题。

这里发生了什么:

str.tr(':,', '') # => "policy allow denied closed"
str.tr(':,', '').split # => ["policy", "allow", "denied", "closed"]
str.tr(':,', '').split[1..-1] # => ["allow", "denied", "closed"]

记住尽可能简单地完成任务,然后在出现问题时变得更复杂,这一点非常重要。可维护性是第一关注的问题,轻率使用的正则表达式可能是一种痛苦。正确使用它的功能非常强大,但它并不是万能的万能药,并不是一切都需要被正则表达式锤击中。

答案 2 :(得分:0)

Ruby的Regexp支持 lookahead lookbehind 。在您的情况下,您可以使用正面的背后隐藏

str = 'policy :allow, :denied, :closed'
policies = str.scan /(?<=:)\w+/
#=> ["allow", "denied", "closed"]

上面的正则表达式查找单词 \w+以冒号 (?<=:)为前缀。请注意,(?<=)是所谓的正向后视,这是一个零长度匹配。

答案 3 :(得分:0)

一种解决方案可以是:

str = 'policy :allow, :denied, :closed'  # "policy :allow, :denied, :closed"
arr = str.split(":")  # ["policy ", "allow, ", "denied, ", "closed"]
arr = arr.pop(arr.length - 1)  # ["allow, ", "denied, ", "closed"]
arr.map{|text| text.gsub(", ", "")} # ["allow", "denied", "closed"]