目前我正在按模式拆分字符串,如下所示:
outcome_array=the_text.split(pattern_to_split_by)
问题是,我所分割的模式本身总是被忽略。
如何使它包含拆分模式本身?
最佳答案
感谢马克·威尔金斯的参与,但这里有一个简短的代码:
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)
通过一次将两个元素传递给它的块来提供帮助。让我们调用each_slice(2)
来查看结果。由于在没有块的情况下调用each_slice
将返回一个枚举数,因此我们将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
将其输入数组的每个元素传递给块;块的结果将成为输出数组中该位置的新元素。在MRI>=1.8.7中,您可以将其进一步缩短为等效值:s.split(/(on)/).each_slice(2).map(&:join)
关于ruby - 将字符串拆分为列表,但保留拆分模式,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/6957858/