目前我正在按照模式将一个字符串拆分,像这样:
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)
可以通过一次传递两个元素到其块中来帮助完成此操作。让我们只是调用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)
s = "split on the word on okay?"
s.split(/(?<=on)/)
=> ["split on", " the word on", " okay?"]
或者使用正向预查,在“on”之前进行拆分:
s = "split on the word on okay?"
s.split(/(?=on)/)
=> ["split ", "on the word ", "on okay?"]
如果您使用这样的方法,您可能希望确保“on”不是更大单词(例如“assertion”)的一部分,并删除分割处的空格:
"don't split on assertion".split(/(?<=\bon\b)\s*/)
=> ["don't split on", "assertion"]
irb(main):007:0> "split it here and here okay".split(/ (here) /)
=> ["split it", "here", "and", "here", "okay"]
编辑:附加信息表明,目标是将被拆分的项之一与其一半包含在一起。我认为有一种简单的方法可以做到这一点,但我不知道它是什么,并且今天没有时间去尝试。因此,在没有巧妙的解决方案的情况下,以下是一种强制性的方法。使用上面描述的split
方法将拆分项包含在数组中。然后遍历数组并将每个第二个条目(根据定义是拆分值)与前一个条目组合在一起。s = "split on the word on and include on with previous"
a = s.split(/(on)/)
# iterate through and combine adjacent items together and store
# results in a second array
b = []
a.each_index{ |i|
b << a[i] if i.even?
b[b.length - 1] += a[i] if i.odd?
}
print b
转化为以下结果:
["split on", " the word on", " and include on", " with previous"]
'split it '
这个分割出来的部分呢? - Andrew Grimm