ruby - 将字符串拆分为列表,但保持拆分模式

标签 ruby string split

目前我正在按模式拆分字符串,如下所示:

outcome_array=the_text.split(pattern_to_split_by)

问题是我分割的模式本身总是被省略。

我如何让它包含拆分模式本身?

最佳答案

感谢 Mark Wilkins 的启发,但这里有一段较短的代码:

irb(main):015:0> s = "split on the word on okay?"
=> "split on the word on okay?"
irb(main):016:0> b=[]; s.split(/(on)/).each_slice(2) { |s| b << s.join }; b
=> ["split on", " the word on", " okay?"]

或:

s.split(/(on)/).each_slice(2).map(&:join)

请参阅下面的解释。


这是它的工作原理。首先,我们在“on”上拆分,但将其括在括号中以使其成为一个匹配组。当传递给 split 的正则表达式中有匹配组时,Ruby 将在输出中包含该组:

s.split(/(on)/)
# => ["split", "on", "the word", "on", "okay?"

现在我们要将“on”的每个实例与前面的字符串连接起来。 each_slice(2) 通过一次将两个元素传递到它的 block 来提供帮助。让我们调用 each_slice(2) 看看有什么结果。由于 each_slice,在没有 block 的情况下调用时,将返回一个枚举器,我们将 to_a 应用于枚举器,以便我们可以看到枚举器将枚举的内容:

s.split(/(on)/).each_slice(2).to_a
# => [["split", "on"], ["the word", "on"], ["okay?"]]

我们越来越近了。现在我们所要做的就是将单词连接在一起。这让我们得到了上面的完整解决方案。我将把它拆成单独的行以便于理解:

b = []
s.split(/(on)/).each_slice(2) do |s|
  b << s.join
end
b
# => ["split on", "the word on" "okay?"]

但是有一个绝妙的方法可以消除临时的 b 并大大缩短代码:

s.split(/(on)/).each_slice(2).map do |a|
  a.join
end

map 将其输入数组的每个元素传递给 block ;该 block 的结果成为输出数组中该位置的新元素。在 MRI >= 1.8.7 中,您可以将其缩短得更短,相当于:

s.split(/(on)/).each_slice(2).map(&:join)

关于ruby - 将字符串拆分为列表,但保持拆分模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6957858/

相关文章:

ruby-on-rails - FactoryGirl中如何通过关联链传递参数

c - 将字符串传递给函数

java - 如何读入和拆分由空格和正斜杠分隔的数字字符串

c - 如何检查字符串是否包含特定字符?

string - 使用不正确的字符串格式时如何从编译器获取消息

python - 上下文正则表达式分割

perl - 在 Perl 中从文件中分割字符串

ruby-on-rails - 可以使用 Ruby 1.8.5 吗?

ruby-on-rails - rails : check if the model was really saved in after_save

ruby 方法 - 如何减少方法中的参数数量?