2016-03-25 85 views
0

我試圖製作一個方法,它將一個哈希鍵中的一部分與輸入中的值進行比較。關鍵看起來喜歡這樣的:以冒號開頭的單詞分割字符串

policy :allow ,:denied ,:closed 

我試圖分裂這個鍵只得到allowdeniedclosed這樣我可以比較那些我得到的輸入值。

我現在有這個權利:

key.split(/: */) 

這給了我:

policy closed, allow, denied 

如何擺脫的第一個字policy,的?

+0

你的問題涉及字符串操作。字符串是哈希鍵的事實是無關緊要的。提到只有泥水。你需要將你的字符串用單引號或雙引號括起來,使其成爲一個有效的Ruby對象,既可以闡明它是什麼,也可以幫助剪切和粘貼(並避免降低成本)。當你舉一個例子時,總是顯示你想要的輸出(作爲一個有效的Ruby對象),併爲每個輸入對象('str =「policy:allow,:denied,:close」')分配一個變量,以便讀者可以參考這些變量答案和評論而不必定義它們。 –

回答

0

Ruby的Regexp支持先行回顧後。在你的情況下,你可以使用積極的後視。上述

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

正則表達式查找詞語\w+其是用冒號(?<=:)前綴。請注意,(?<=)被稱爲積極lookbehind,這是一個零長度匹配。

+0

嘿,你能解釋一下你使用的正則表達式嗎? :) – FroggyFreshh

+1

完美有效的紅寶石代碼:'政策:✓,:✗'幾乎不會通過這個正則表達式,儘管OP沒有提及_real的意圖。 – mudasobwa

+1

@mudasobwa:哦來吧:)這是一個合理的假設,我會說。 –

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"] 
+1

而不是'arr = arr.pop(arr.length - 1)'一個簡單的'arr.shift'就足夠了。 –

+0

@theTinMan感謝您的指針。 – Abhi

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

我沒有看到一個正則表達式的任何需求:

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"] 

這真的很重要的是要記住,開始儘可能簡單完成目標任務的,然後得到如果出現問題更爲複雜。可維護性是第一關心的問題,使用的正則表達式可能是一種痛苦。正確使用它是驚人的強大,但它不是一個萬能的靈丹妙藥,並不是所有的東西都需要被正則錘擊中。