Соответствует ли модификатор регулярных выражений Perl /m в Windows по-разному?
Вопрос
Следующие инструкции 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
}