Ist Perl / m Regex Modifikator Spiel anders auf Windows?
Frage
Die folgenden Perl-Anweisungen verhalten sich identisch auf Unixish Maschinen. Verhalten sie sich anders unter Windows? Wenn ja, ist es wegen der Magie? \ N
split m/\015\012/ms, $http_msg;
split m/\015\012/s, $http_msg;
Ich habe einen Ausfall auf einen meines CPAN Module aus einem Win32 Rußzahlmessgerät. Es sieht aus wie es ein \ r \ n vs \ n Problem ist. Eine Änderung, die ich vor kurzem war // m auf meine reguläre Ausdrücke hinzuzufügen.
Lösung
Für diese regulären Ausdrücke:
m/\015\012/ms m/\015\012/s
Beide / m und / s ist bedeutungslos.
- / s: macht
.
Spiel\n
auch. Ihr regex enthält keine.
- / m: macht
^
und$
Spiel neben eingebetteten\n
in der Zeichenkette. Ihre regex enthält keine^
noch$
oder deren Synonyme.
Was möglich ist, ist in der Tat, wenn Sie Ihre Eingabe Griff (Buchse?) Im Textmodus arbeitet, werden sich die \r
(\015
) Zeichen unter Windows gelöscht.
Also, was zu tun? Ich schlage vor, die \015
Zeichen optional machen und Split gegen
/\015?\012/
Keine Notwendigkeit für / m, / s oder sogar die führenden m//
. Das ist nur Cargo-Kult.
Andere Tipps
Es gibt keine magische \n
. Sowohl \n
und \r
immer bedeuten, genau ein Zeichen, und auf allen ASCII-basierten Plattformen, ist \cJ
und \cM
ist. (Ausnahmen sind EBCDIC-Plattformen (aus offensichtlichen Gründen) und MacOS Classic (wo \n
und \r
beide bedeuten \cM
).)
Die Magie, die auf Windows passiert ist, dass, wenn I / O über eine Datei-Handle zu tun, die als im Textmodus markiert ist, \r\n
übersetzt wird beim Lesen und umgekehrt beim Schreiben \n
. (Außerdem ist \cZ
verstanden, End-of-Datei - Überraschung). Dies wird in der C-Laufzeitbibliothek Schicht durchgeführt
Sie müssen binmode
Ihre Steckdose zu reparieren.
Sie sollten auch den /s
und /m
Modifikatoren von Ihrem Muster entfernen: da Sie die Meta-Zeichen nicht dessen Verhalten verwenden sie ändern (.
und das ^
/ $
Paar, respectively), sie tun nichts - Cargo-Kult
Warum fügen Sie die /m
? Versuchen Sie, auf Linie zu teilen? Um das zu tun mit /m
benötigen Sie entweder ^
oder $
in der Regex verwenden:
my @lines = split /^/m, $big_string;
Wenn Sie jedoch wollen eine große Zeichenfolge als Linien zu behandeln, öffnen Sie einfach einen Dateihandle auf einem Verweis auf die skalare:
open my $string_fh, '<', \ $big_string;
while( <$string_fh> ) {
... process a line
}