目前我正在按照模式分割一个字符串:
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","okay?"
现在我们要用上面的字符串加入每个“on”的实例. each_slice(2)通过一次传递两个元素来帮助其阻止.我们来调用every_slice(2)来查看结果.由于each_slice在没有块的情况下调用时,将返回一个枚举器,因此我们将向枚举器应用to_a,以便我们可以看到枚举器将枚举器的内容:
s.split(/(on)/).each_slice(2).to_a # => [["split","on"],["the word",["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
映射将其输入数组的每个元素传递给块;该块的结果将成为输出数组中该位置的新元素.在MRI中= 1.8.7,您可以将其缩短到相当于:
s.split(/(on)/).each_slice(2).map(&:join)