Vous n'avez pas besoin d'une expression régulière sophistiquée pour faire ce que vous voulez, il vous suffit de savoir comment procéder.
La méthode Enumerable de Ruby s'appelle slice_before
qui prend une expression régulière, utilisée pour déterminer quels éléments du tableau sont regroupés. Array hérite de Enumerable. Par exemple :
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
Sorties :
[["#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"]]
En d'autres termes, le tableau créé en divisant le texte sur "\n"
est regroupé par lignes ne commençant pas par un espace blanc, ce qui correspond au modèle /\A\S/
. Toutes les lignes simples se trouvent dans des sous-ensembles distincts. Les lignes qui sont des suites de la ligne précédente sont regroupées avec cette dernière.
Si vous lisez un fichier à partir d'un disque, vous pouvez utiliser la fonction IO.readlines
pour lire le fichier sous la forme d'un tableau, ce qui évite d'avoir à diviser le fichier.
Vous pouvez traiter ce tableau plus avant, si vous le souhaitez, pour reconstruire les lignes et les lignes de suite, en utilisant quelque chose comme :
data = text.split("\n").slice_before(/\A\S/).map{ |i| i.join("\n") }
Qui tourne data
en :
["#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"]
Si vous avez besoin de diviser chaque ligne en ses champs constitutifs, utilisez la fonction split("\t")
. La manière de procéder pour les sous-réseaux est un exercice que vous pouvez faire, mais j'impliquerais map
.
EDITAR:
...J'aime votre solution, mais j'obtiens une méthode non définie pour slice_before.
Essayez ceci :
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
Appeler cela :
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/)
On dirait que.. :
[
["#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"]
]