У вас есть в списке несколько событий, которые могут произойти в игре в бейсбол: называется удар, мяч, удвоение и вылет.Это, конечно, только верхушка айсберга: вылет, фол, одиночный, тройной, домашний бег, жертва, ошибка, украденное основание, выброшенная попытка кражи, двойная игра, тройная игра и другие.Чтобы информация о событии была полезной, каждый тип события должен рассматриваться отдельно.Попытка сделать это с помощью одного регулярного выражения, по моему мнению, глупо.Ниже представлен подход, который можно рассмотреть.Оператор case
должен быть значительно расширен, чтобы включать, помимо прочего, события, о которых я упоминал выше.
Код
def parse_events(arr)
arr.map do |s|
event = s[/\p{Lu}[\p{L} ]*(?=\,|\z)/].strip.downcase
{ event: event, count: s[0,3] }.merge(
case event
when "called strike", "ball"
{}
when "foul ball"
{ location: s[/\d\p{L}+\z/] }
when "double"
{ type: s[/(?<=\()[\p{L} ]+/].downcase,
location: s[/\d\p{L}+(?=\)\z)/] }
when "ground out"
{ sequence: s[/(?<=, )\d\-\d/],
type: s[/(?<=\()[\p{L} ]+/],
location: s[/\d+(?=\)\z)/] }
else
# raise exception
end)
end
end
Пример
arr = <<-END.split("\n").map(&:strip)
0-0: Called Strike
0-1: Foul ball, location: 2F
0-2: Double, (Line Drive, 3D)
0-0: Foul Ball, location: 2F
0-1: Ball
1-1: Double, (Line Drive, 9LD)
0-0: Called Strike
0-1: Ball
1-1: Foul Ball, location: 2F
1-2: Ball
2-2: Ball
3-2: Ground out, 3-1 (Groundball, 34)
END
#=> ["0-0: Called Strike",
# "0-1: Foul ball, location: 2F",
# "0-2: Double, (Line Drive, 3D)",
# "0-0: Foul Ball, location: 2F",
# "0-1: Ball",
# "1-1: Double, (Line Drive, 9LD)",
# "0-0: Called Strike",
# "0-1: Ball",
# "1-1: Foul Ball, location: 2F",
# "1-2: Ball",
# "2-2: Ball",
# "3-2: Ground out, 3-1 (Groundball, 34)"]
parse_events arr
#=> [{:event=>"called strike", :count=>"0-0"},
# {:event=>"foul ball", :count=>"0-1", :location=>"2F"},
# {:event=>"double", :count=>"0-2", :type=>"line drive", :location=>"3D"},
# {:event=>"foul ball", :count=>"0-0", :location=>"2F"},
# {:event=>"ball", :count=>"0-1"},
# {:event=>"double", :count=>"1-1", :type=>"line drive", :location=>"9LD"},
# {:event=>"called strike", :count=>"0-0"},
# {:event=>"ball", :count=>"0-1"},
# {:event=>"foul ball", :count=>"1-1", :location=>"2F"},
# {:event=>"ball", :count=>"1-2"},
# {:event=>"ball", :count=>"2-2"},
# {:event=>"ground out", :count=>"3-2", :sequence=>"3-1",
# :type=>"Groundball", :location=>"34"}]