Почему этот код пропускает все остальные строки ввода - PullRequest
2 голосов
/ 09 октября 2019

Я пытаюсь перебрать данные с помощью регулярного выражения и анализировать каждую строку по дате (т.е. 7/9/2019). Тем не менее, результаты опускают все остальные строки во входных данных.

Пробовал это в Windows и Mac (Terminal shell) к тому же поведению последовательно.

my $file;

{
    local $/ = undef;
    $file = <DATA>;
}

while ($file =~ m/(\d\/\d\/\d{4}.*?)\d\/\d\/\d{4}/gs) {
    print "*$1*\n";
}

__DATA__
9/7/2019 20:35:17,dog
9/7/2019 21:06:16,cat
9/7/2019 22:32:15,parrot
9/7/2019 22:32:15,snail
9/7/2019

Я ожидаю следующее:

*9/7/2019 20:35:17,dog*
*9/7/2019 21:06:16,cat*
*9/7/2019 22:32:15,parrot*
*9/7/2019 22:32:15,snail*

, но вместо этого получите следующее:

*9/7/2019 20:35:17,dog
*
*9/7/2019 22:32:15,parrot
*

Ответы [ 2 ]

3 голосов
/ 09 октября 2019

Вы не инкапсулируете конец своего паттерна. Измените цикл while на:

 while ($file =~ m/(\d\/\d\/\d{4}.*?)(?=\R\d\/\d\/\d{4})/gs) {
    print "*$1*\n";
}

Это должно работать для вас. Проверьте это по адресу: https://rextester.com/l/perl_online_compiler

2 голосов
/ 09 октября 2019

Ваш шаблон соответствует двум датам, поэтому следующее совпадение будет продолжаться, фактически пропуская строку.

Нет смысла проверять, начинается ли следующая строка с даты, поэтому вы можете использовать

while (<DATA>) {
   next if !m{^(\d+/\d+/\d+)};

   print "*$1*\n";
}

Если вы не читали из файла:

while ($file =~ m{^(\d+/\d+/\d+)}mg) {
   print "*$1*\n";
}

Если каждая строка начинается с даты, вы можете даже использовать

while (<DATA>) {
   my @fields = split;
   print "*$fields[0]*\n";
}

Если вы неt чтение из файла:

while ($file =~ /^(.*)/mg) {
   my @fields = split;
   print "*$1*\n";
}

Отсутствие /s означает, что . не будет соответствовать переводу строки, что означает, что он не будет совпадать после конца строки.

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