Как вставить двоеточие между словом и числом - PullRequest
0 голосов
/ 11 октября 2018

Я хочу вставить двоеточие между словом и числом, а затем добавить новую строку после числа.Например:

"cat 11052000 cow_and_owner_ 01011999 12031981 dog 22032011";

мой ожидаемый результат:

cat:11052000
cow_and_owner_:01011999 12031981
dog:22032011

Моя попытка:

$Bday=~ /^([a-z]||\_)/:/^([0-9])/
print "\n";

Ответы [ 3 ]

0 голосов
/ 12 октября 2018

Еще один вариант -

> cat test_perl.pl
#!/usr/bin/perl
use strict;
use warnings;
while ( "cat 11052000 cow_and_owner_ 01011999 12031981 dog 22032011" =~ m/([a-z_]+)\s+([0-9 ]+)/g )
{
print "$1:$2\n";
}
> test_perl.pl
cat:11052000
cow_and_owner_:01011999 12031981
dog:22032011
>
0 голосов
/ 13 октября 2018

Оригинальный код $Bday=~ /^([a-z]||\_)/:/^([0-9])/ не имеет особого смысла.Помимо пропуска точки с запятой и слишком большого количества разделителей (совпадающие шаблоны имеют формат /.../ или m/.../ и заменяющие их s/.../.../), он никогда не сможет ничего сопоставить.

  1. ([a-z]||\_) будет соответствовать:

    • одна строчная буква ASCII (от a до z);
    • пустая строка (пробел междудва | s или
    • одно подчеркивание (экранирование с обратной косой чертой излишне).

    Чтобы получить его (или соответствующее подвыражение для чисел), чтобы соответствовать последовательностиодин или несколько символов, вам нужно следовать за ним с +.

  2. ^([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;
0 голосов
/ 11 октября 2018
#!/usr/bin/perl
use warnings;
use strict;
my $str = "cat 11052000 cow_and_owner_ 01011999 12031981 dog 22032011";
$str =~ s/\s*([a-z_]+)((?: \d+)+)/$1:$2\n/g;
print $str;

производит желаемый вывод из вашего образца ввода.

Редактировать: Обратите внимание на использование оператора s для замены регулярного выражения.Одна из многих проблем с вашим кодом заключается в том, что вы этим не пользуетесь (ЕСЛИ вы намереваетесь изменить строку и не извлекать из нее биты для дальнейшей обработки)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...