Соответствует ли модификатор регулярных выражений Perl /m в Windows по-разному?

StackOverflow https://stackoverflow.com/questions/214517

  •  03-07-2019
  •  | 
  •  

Вопрос

Следующие инструкции Perl ведут себя идентично на машинах Unixish.Ведут ли они себя по-другому в Windows?Если да, то это из-за магии ?

  split m/\015\012/ms, $http_msg;
  split m/\015\012/s, $http_msg;

У меня есть неудача на одном из моих модулей CPAN из тестера дыма Win32.Похоже, что это проблема \ r \ n vs \ n.Одно изменение, которое я внес недавно, заключалось в добавлении //m к моим регулярным выражениям.

Это было полезно?

Решение

Для этих регулярных выражений:

m/\015\012/ms
m/\015\012/s

И /m, и / s не имеют смысла.

  • /с:делает . совпадение \n слишком.Ваше регулярное выражение не содержит .
  • /м:делает ^ и $ сопоставьте рядом со встроенным \n в строке.Ваше регулярное выражение не содержит ^ ни $, или их синонимы.

Что действительно возможно, так это если ваш дескриптор ввода (сокет?) работает в текстовом режиме, \r (\015) символы будут удалены в Windows.

Итак, что же делать?Я предлагаю сделать следующее \015 символы необязательны и разделяются по отношению

/\015?\012/

Нет необходимости в /m, / s или даже в ведущей m//.Это просто культ карго.

Другие советы

Магии нет \ n . И \ n , и \ r всегда означают ровно один символ, и на всех основанных на ASCII платформах это \ cJ и \ cM соответственно. (Исключение составляют платформы EBCDIC (по понятным причинам) и MacOS Classic (где \ n и \ r оба означают \ cM ).)

Волшебство, которое происходит в Windows, заключается в том, что при выполнении ввода-вывода через дескриптор файла, помеченный как находящийся в текстовом режиме, \ r \ n переводится в \ n при чтении и наоборот при написании. (Также \ cZ означает конец файла & # 8211; сюрприз!) Это делается на уровне библиотеки времени выполнения C.

Вам нужно binmode свой сокет, чтобы это исправить.

Вы также должны удалить модификаторы / s и / m из вашего шаблона: поскольку вы не используете метасимволы, поведение которых они изменяют (. и пара ^ / $ соответственно), они ничего не делают & # 8211; культ груза.

Почему вы добавили / m ? Вы пытаетесь разделить на линии? Чтобы сделать это с помощью / m , вам необходимо использовать ^ или $ в регулярном выражении:

my @lines = split /^/m, $big_string;

Однако, если вы хотите обрабатывать большую строку как строки, просто откройте дескриптор файла со ссылкой на скаляр:

open my $string_fh, '<', \ $big_string;
while( <$string_fh> ) {
    ... process a line
    }
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top