你不需要花哨的正则表达式来做你想做的事,你只需要知道如何去做。
Ruby 的 Enumerable 有一个称为slice_before
正则表达式的方法,用于确定数组中的哪些元素被组合在一起。Array 继承自 Enumerable。例如:
text = '#3 Hello Stormy Scratched - Reason Unavailable 11:10 AM ET
#3 Hello Stormy Scratched - Reason Unavailable 11:10 AM ET
Scratch Reason - Reason Unavailable changed to Trainer 2:19 PM ET
'
data = text.split("\n").slice_before(/\A\S/).to_a
require 'pp'
pp data
输出:
[["#3\tHello Stormy\tScratched\t-\tReason Unavailable\t\t\t11:10 AM ET"],
["#3\tHello Stormy\tScratched\t-\tReason Unavailable\t\t\t11:10 AM ET",
"\t\t\tScratch\tReason\t-\tReason Unavailable changed to Trainer\t2:19 PM ET"]]
换句话说,通过拆分文本创建的数组"\n"
按不以空格开头的行分组,这就是模式/\A\S/
。所有单行都在单独的子阵列中。作为前一行的延续的行与该行分组。
如果您正在从磁盘读取文件,则可以使用IO.readlines
将文件作为数组读取,从而避免拆分文件的需要。
如果需要,您可以进一步处理该数组以重建行和续行,使用类似:
data = text.split("\n").slice_before(/\A\S/).map{ |i| i.join("\n") }
变成data
:
["#3\tHello Stormy\tScratched\t-\tReason Unavailable\t\t\t11:10 AM ET",
"#3\tHello Stormy\tScratched\t-\tReason Unavailable\t\t\t11:10 AM ET\n\t\t\tScratch\tReason\t-\tReason Unavailable changed to Trainer\t2:19 PM ET"]
如果您需要将每一行拆分为其组件字段,请使用split("\t")
. 如何在子阵列中执行此操作留给您作为练习,但我会涉及map
.
编辑:
...我喜欢你的解决方案,但我得到了 slice_before 的未定义方法。
尝试这个:
require 'pp'
require 'rubygems'
class Array
unless Array.respond_to?(:slice_before)
def slice_before(pat)
result = []
temp_result = []
self.each do |i|
if (temp_result.empty?)
temp_result << i
next
end
if i[pat]
result << temp_result
temp_result = []
end
temp_result << i
end
result << temp_result
end
end
end
这么称呼:
ary = [
'#3 Hello Stormy Scratched - Reason Unavailable 11:10 AM ET',
'#3 Hello Stormy Scratched - Reason Unavailable 11:10 AM ET',
' Scratch Reason - Reason Unavailable changed to Trainer 2:19 PM ET',
]
pp ary.slice_before(/\A\S/)
好像:
[
["#3 Hello Stormy Scratched - Reason Unavailable 11:10 AM ET"],
["#3 Hello Stormy Scratched - Reason Unavailable 11:10 AM ET",
" Scratch Reason - Reason Unavailable changed to Trainer 2:19 PM ET"]
]