我写你的数据文件“临时”:
首先定义用于提取感兴趣的文件的行正则表达式。
r =/
Head\s+\d+ # match 'Head', > 0 spaces, ?= 1 digits in capture group 1
| # or
[[:lower:]]+\s+88 # match > 0 lower case letters, > 0 spaces, '88'
/xm # free-spacing regex definition and multi-line modes
现在对该文件执行以下操作。
File.read('temp').scan(r).
slice_before { |line| line.start_with?('Head ') }.
reject { |a| a.size == 1 }.
flat_map { |head, *rest| [head].product(rest) }.
map { |a| "%s, %s" % a }
#=> ["Head 1, f 88", "Head 4, t 88", "Head 33, v 88",
# "Head 32, n 88", "Head 32, b 88"]
步骤如下。
a = File.read('temp').scan(r)
#=> ["Head 1", "f 88", "Head 4", "t 88", "Head 53", "Head 33",
# "v 88", "Head 32", "n 88", "b 88"]
b = a.slice_before { |line| line.start_with?('Head') }
#=> #<Enumerator: #<Enumerator::Generator:0x007ffd218387b0>:each>
我们可以看到,通过将枚举b
通过将其转换到一个阵列产生的元素。
b.to_a
#=> [["Head 1", "f 88"], ["Head 4", "t 88"], ["Head 53"],
# ["Head 33", "v 88"], ["Head 32", "n 88", "b 88"]]
现在从b
中删除所有大小为1的数组。
c = b.reject { |a| a.size == 1 }
#=> [["Head 1", "f 88"], ["Head 4", "t 88"], ["Head 33", "v 88"],
# ["Head 32", "n 88", "b 88"]]
接下来我们使用Enumerable#flat_map和Array#product每个“头”与以下所有线路为此88\n
(前下一个“头”或文件的末尾)相关联。
d = c.flat_map { |head, *rest| [head].product(rest) }
#=> [["Head 1", "f 88"], ["Head 4", "t 88"], ["Head 33", "v 88"],
# ["Head 32", "n 88"], ["Head 32", "b 88"]]
最后,将d
的每个元素转换为一个字符串。
d.map { |a| "%s, %s" % a }
#=> ["Head 1, f 88", "Head 4, t 88", "Head 33, v 88",
# "Head 32, n 88", "Head 32, b 88"]
你想抓住所有具有“88”值的东西吗?这个问题还不清楚。另外,请告诉我们你已经尝试了什么。 – mudasobwa
@il_raffa感谢编辑 – Misha1991
@Mudasobwa是的,我想选择所有记录与88和他们的头文件 – Misha1991