如果我有一個像下面這樣的字符串,我會如何在每個第三個字符或任何其他指定的字符處分割它?如何在Ruby中對某個字符進行分片或分割字符串?
b = "123456789"
,結果會是這樣:
b = ["123","456","789"]
我一直使用這些方法的嘗試:b.split("").each_slice(3).to_a
但它會導致這樣的:[["1", "2", "3"], ["4", "5", "6"], ["7", "8", "9"]]
謝謝您的幫助!
如果我有一個像下面這樣的字符串,我會如何在每個第三個字符或任何其他指定的字符處分割它?如何在Ruby中對某個字符進行分片或分割字符串?
b = "123456789"
,結果會是這樣:
b = ["123","456","789"]
我一直使用這些方法的嘗試:b.split("").each_slice(3).to_a
但它會導致這樣的:[["1", "2", "3"], ["4", "5", "6"], ["7", "8", "9"]]
謝謝您的幫助!
你幾乎做到了。
b = "123456789"
b.split("").each_slice(3).map(&:join) # => ["123", "456", "789"]
b = "123456789"
b.chars.each_slice(3).map(&:join)
# => ["123", "456", "789"]
我會使用:
b = "123456789"
b.scan(/.{3}/) # => ["123", "456", "789"]
如果OP的樣品都將在不同的長度,或者它有一個嵌入 「\ n」,一個簡單的改造工程:
b = "123456789"
b.scan(/.{1,3}/) # => ["123", "456", "789"]
b[0..-2].scan(/.{1,3}/) # => ["123", "456", "78"]
"#{ b }\n#{ b }".scan(/.{1,3}/) # => ["123", "456", "789", "123", "456", "789"]
現在,如果在偶數的「3」邊界上存在嵌入的「\ n」NOT,它遊:
"#{ b[0..-2] }\n#{ b }".scan(/.{1,3}/) # => ["123", "456", "78", "123", "456", "789"]
但越來越相當遙遠從OP的簡單的規範,並且可以通過剝離新線(S)固定第一:
"#{ b[0..-2] }\n#{ b }".delete("\n").scan(/.{1,3}/) # => ["123", "456", "781", "234", "567", "89"]
這不會創建臨時數組,適用於任何集合和數量的字符,不使用慢速正則表達式。雖然沒有那麼優雅。
s = "1234567"
(0...s.size/3).map { |i| s[i * 3, 3] }
# => ["123", "456", "7"]
基準:
require "benchmark"
N = 100000
Benchmark.bm do |x|
b = "123456789"
x.report { N.times { (0...b.size/3).map { |i| b[i * 3, 3] } } }
x.report { N.times { b.scan(/.{3}/) } }
x.report { N.times { b.chars.each_slice(3).map(&:join) } }
x.report { N.times { b.split("").each_slice(3).map(&:join) } }
end
結果:
$ ruby split3.rb
user system total real
0.080000 0.000000 0.080000 ( 0.079944)
0.130000 0.000000 0.130000 ( 0.127715)
0.300000 0.000000 0.300000 ( 0.299186)
0.640000 0.000000 0.640000 ( 0.641817)
我試圖改變行的順序,看看是否有任何奇怪的副作用。結果是一致的。訂單無關緊要。
如果只有某人對所有這些答案進行基準測試...... :) –
我對它進行了基準測試。 – detunized
's =「12 \ n3456 \ n7」; (0 ... s.size/3).map {| i | s [i * 3,3]}#=> [「12 \ n」,「345」,「6 \ n7」]'。 –
除了其他答案,如果你想分裂一個任意的字符集(這個答案不包括每個第三個字符,因爲已經有足夠多的答案),並決定其中分裂字符去,你也可以使用split
像這樣:
# Split and include splitting character in next slice
"123456789".split(/(?=[36])/) # => ["12", "345", "6789"]
# Split and include splitting character in slice
"123456789".split(/(?<=[36])/) # => ["123", "456", "789"]
# Split and exclude character from slices
"123456789".split(/[36]/) # => ["12", "45", "789"]
記住,這確實使用正則表達式,併爲你的目的,它可能是更好的使用在尋找一種方法來分割字符串少(請參閱detunized的答案,這是相當簡潔和合理的方式來處理這個問題)。根據被拆分字符串的複雜程度,你分裂的內容,如何分割字符/短語等等,你的方法可能會改變。
另一種方式:
my_s, my_a = '123456789', []
my_a << my_s.slice!(0..2) until my_s.empty?
p my_a # => ["123", "456", "789"]
非常好的研究.. :)我喜歡。 –
不錯。可以用'shift(3)'代替'slice!(0..2)'。 –
我正在使用切片!在atring上。字符串不是可枚舉的(如果我沒有記錯的話,從1.9開始)。 – hirolau
權。如果我正確理解要求,這是一個更好的答案 –
+1漂亮和優雅。如果'b.length%3!= 0'不起作用,但是這樣做:'b.scan(/..?.?/)' – iamnotmaynard
如果你有''\ n「'串。 – detunized