Запись Perl в «файл памяти» воспроизводит трюки с сопоставлением с образцом - PullRequest
11 голосов
/ 28 декабря 2011

Когда я запускаю этот код, я получаю распечатанное "нет":

my $memory_file;
my $fh;
open ($fh, '>', \$memory_file);
print $fh "abc";
if( $memory_file =~ m/^.*$/ )
{ print "yes\n" }
else
{ print "no\n" }

Если я распечатаю $memory_file, содержимое действительно "abc".

Если яизмените шаблон на .* (без ^ или $), он будет работать, как и ожидалось.

Если я поставлю строку $memory_file = "abc" перед совпадением, я получу распечатанное «да» (как первоначальноожидается).

Что здесь происходит?

(Это perl 5.14.1)

Обновление: Еще немного дискуссий по PerlMonks .Это похоже на ошибку, я войду в нее.

Обновление 2: Хорошие разработчики Perl исправили эту ошибку: https://rt.perl.org/rt3//Public/Bug/Display.html?id=108398

Ответы [ 4 ]

5 голосов
/ 28 декабря 2011

Это символ конца строки, который все портит.Пока работает обычное задание:

my $str = "abc";
print "Works" if $str =~ /^.*$/;

... код в вопросе не работает.Это регулярное выражение должно соответствовать любой строке, так как оно также соответствует пустой строке.Даже неопределенные значения будут соответствовать (хотя это вызовет предупреждение).Кроме того, ^.* соответствует.

Единственное разумное объяснение состоит в том, что по какой-то причине, какая бы проверка ни выполнялась для соответствия концу строки, она не находит ее.Конец строки отсутствует.

Любопытно, что замена $ на \z работает.Но не \Z.

Добавление новой строки также работает.Это имело бы смысл, так как добавление новой строки означало бы, что конец строки также добавляется в смысле не-многострочного регулярного выражения.

Я не знаю, как это происходит,но я подозреваю, что при использовании этой конкретной формы «присваивания» в строку никогда не помещается маркер конца строки.Это своего рода «сырое» присваивание, которое путает проверку конца строки в регулярном выражении.

Это похоже на ошибку.Возможно, эта особенность не была должным образом поддержана.

2 голосов
/ 28 декабря 2011

Я думаю, что проблема в новой строке и $ привязке.Он проверяет строку после новой строки, а ваша строка ее не имеет.

РЕДАКТИРОВАТЬ :

См. Подробное объяснение проблемы в других ответах, поскольку мой былневерен.Но я дам два варианта для ее решения:

  • Запишите «abc \ n» в свой файл и проверьте с помощью $
  • Проверьте конец строки с помощью \z.
2 голосов
/ 28 декабря 2011

просто используйте вспомогательную переменную.

#$| = 1; # AutoFlush

my $memory_file;
open ( my $fh, '>>', \$memory_file) or die $!;
print $fh "abc";

my $buff = $memory_file;

if( $buff =~ m/^abc$/ ){ # or m/^.*$/
    print "yes\n"; 
}else{ 
    print "no\n";
}
0 голосов
/ 28 декабря 2011

Ну, мой первый инстинкт - сказать, что файлы в памяти не действуют так же, как физические файлы. Попробуйте изменить print $fh "abc"; на print $fh "abc\n";, чтобы увидеть, превращается ли ваш ввод в строку.

Мой другой инстинкт заключается в том, что ваш файл на самом деле не записывается, пока вы не прочитали его. Очистите буфер с помощью $|++;

Итак, попробуйте:

my $memory_file;
my $fh;
open ($fh, '>', \$memory_file);
print $fh "abc";
$|++;
if( $memory_file =~ m/^.*$/ )
{ print "yes\n" }
else
{ print "no\n" }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...