Perl шаблон соответствия переменной вопрос - PullRequest
2 голосов
/ 06 января 2011

Я пытаюсь открыть файл, сопоставить определенную строку, а затем обернуть HTML-теги вокруг этой строки.Кажется ужасно простым, но, по-видимому, я что-то упускаю и не правильно понимаю переменные сопоставления шаблонов Perl.

Я сопоставляю строку с этим:

$line =~ m/(Number of items:.*)/i;

, который помещает вселиния в $ 1.Затем я пытаюсь распечатать мою новую строку следующим образом:

print "<p>" . $1 . "<\/p>;

Я ожидаю, что она напечатает это:

<p>Number of items: 22</p>

Тем не менее, я на самом деле получаю это:

</p>umber of items: 22

Я испробовал все виды вариаций - печатая каждый бит в отдельной строке, устанавливая $ 1 в новую переменную, используя $ + и $ &, и т. Д., И я всегда получал один и тот же результат.

Чего мне не хватает?

Ответы [ 3 ]

9 голосов
/ 06 января 2011

В вашем совпадении есть \ r, что при печати приводит к искаженному выводу.

редактирование: Чтобы объяснить далее, скорее всего, ваш файл имеет оконный стиль \ r \ n окончания строки. chomp не удалит \ r, что приведет к попаданию в ваше жадное совпадение и приведет к неприятным выводам (\ r означает вернуться к началу строки и продолжить печать).

Вы можете удалить \ r, добавив что-то вроде

$line =~ tr/\015//d;
3 голосов
/ 06 января 2011

Вы только что узнали (для дальнейшего использования), насколько опасным может быть .*.

Ударяя головой о подобные неприятности, в эти дни мне нравится быть настолько точным, насколько я могу, относительно того, что я ожидаюзахватить.Может быть,

$line =~ m/(Number of items:\s+\d+)/;

Тогда я уверен, что в первую очередь я не поймаю оскорбительного управляющего персонажа.Что бы Cygwin ни делал с файлами Windows, я могу оставаться в блаженном неведении.

3 голосов
/ 06 января 2011

Можете ли вы предоставить полный фрагмент кода, который демонстрирует вашу проблему? Я этого не вижу.

Следует с осторожностью сказать, что $ 1 и друзья ссылаются на снимки с последнего успешного совпадения в этой динамической области. Вы должны всегда проверять, что совпадение успешно, прежде чем использовать один:

$line = "Foo Number of items: 97\n";
if ( $line =~ m/(Number of items:.*)/i ) {
    print "<p>" . $1 . "<\/p>\n";
}
...