Оригинальный код $Bday=~ /^([a-z]||\_)/:/^([0-9])/
не имеет особого смысла.Помимо пропуска точки с запятой и слишком большого количества разделителей (совпадающие шаблоны имеют формат /.../
или m/.../
и заменяющие их s/.../.../
), он никогда не сможет ничего сопоставить.
([a-z]||\_)
будет соответствовать:
- одна строчная буква ASCII (от a до z);
- пустая строка (пробел междудва
|
s или - одно подчеркивание (экранирование с обратной косой чертой излишне).
Чтобы получить его (или соответствующее подвыражение для чисел), чтобы соответствовать последовательностиодин или несколько символов, вам нужно следовать за ним с +
.
^([0-9])
, который не будет совпадать, если он не будет в начале строки.соответствует одной цифре.
Мое решение (принимая во внимание более поздние комментарии ОП о наличии ввода, например cat[1]
или dog3
):
use strict;
use warnings;
my $bday = "cat 11052000 cow_and_owner_ 01011999 12031981 dog 22032011 cat[1] 01012018 dog3 02012018";
# capture groups:
# $1------------------------\ $2-------------\
$bday =~ s/([A-Za-z][A-Za-z0-9_\[\]]*)\h+(\d+(?:\h+\d+)*)(?!\S)\s*/$1:$2\n/g;
print $bday;
распечатает:
cat:11052000
cow_and_owner_:01011999 12031981
dog:22032011
cat[1]:01012018
dog3:02012018
Разбивка:
[A-Za-z]
: начинайте с буквы.
[A-Za-z0-9_\[\]]*
: следуйте нулю или более букв, цифр, подчеркиваний и квадратных скобок.
\h+
: разделяйте одним или несколькими горизонтальными пробелами.
\d+(?:\h+\d+)*
: одна последовательность цифр (\d+
), за которой следуют ноль или более последовательностей горизонтального пробела и цифр.
(?!\S)
: можетне должно следовать без пробелов.
\s*
: потреблять следующие пробелы (включая переводы строк;это позволяет разделить входные данные на несколько строк, если одна запись не распределена на несколько строк.Чтобы получить это, замените все \h+
на \s+
.).
Шаблон замены будет повторяться (модификатор /g
) последовательно в исходной строке, пока онсопоставления, помещая каждую запись даты заголовка в отдельной строке, а затем продолжая с остальной строкой.
Обратите внимание, что если ваши заголовки (dog
и т. д.) могут содержать не-ASCII буквы,используйте \pL
или \p{XPosixAlpha}
вместо [A-Za-z]
:
$bday =~ s/\pL[\pL0-9_\[\]]*)\h+(\d+(?:\h+\d+)*)(?!\S)\s*/$1:$2\n/g;