Один из способов получить то, что вам нужно, - это регулярное выражение, учитывая, что у вас есть четкие привязки.
my @parts = $string =~ /
([0-9]+) # numbers for day
(?:[^0-9]+)?\s+ # for st|nd|rd|th (optional!), space. not captured
(\w+)\s+ # month
([0-9]+)\s+ # year
.+? # the rest, but only up to the initials
( (?:WJ|NW|JK|KB|II): .+? INC[0-9]+ )
/x;
Некоторые шаблоны здесь могут быть усилены или ослаблены (например, вместо чередования ожидаемых инициалов мы могли бы иметь [A-Z]+:
, с учетом других и большего количества букв).
Затем преобразуйте время в желаемую метку времени. Хороший инструмент для этого - Time :: Piece . Всего
use warnings;
use strict;
use feature 'say';
use Time::Piece;
my $string = q(16th Jun 2020 7:57:18 am Tom Lewin: WJ: RE: BART failed STP - JIMBCI - INC101981467816th Jun 2020 8:20:38 am Nathan Winslow: II : RE: Loans are experiencing issues sending RUNZ - INC101981521816th Jun 2020 8:57:58 am Nathan Winslow: NW : RE: FW: Missing pool factor PnL [Restricted - Internal] - INC101981603016th Jun 2020 9:13:49 am Nathan Winslow: JK : RE: missing sales credits - INC101981633816th Jun 2020 9:24:26 am Nathan Winslow: KB : RE: Bookbuilder not responding - INC1019816567);
my @parts = $string =~ /
([0-9]+) (?:[^0-9]+)?\s+ (\w+)\s+ (\w+)\s+ .+?
( (?:WJ|NW|JK|KB|II): .+? INC[0-9]+ )
/x;
#say for @parts; say '---';
my $dt = Time::Piece->strptime("@parts[0..2]", "%d %b %Y");
say $dt->mdy('/'), ' ', $parts[3];
Последний бит, возможно, лучше сделать как
my $date = Time::Piece
-> strptime( join(' ', splice @parts, 0, 3), "%d %b %Y")
-> mdy('/');
say "$date @parts";
, где теперь нам не нужно считать точное количество элементов для печати.
В этом случае @parts
в итоге содержит только один элемент, но изменения требований все же происходят. Кроме того, если некоторые элементы на самом деле необходимы как отдельные для других целей (добавьте наборы захватывающих скобок), тогда @parts
будет иметь больше элементов.
Они печатают то, что необходимо.