Schrift
[thread]8623[/thread]

Zeilenumbruch in Perl: Erfasst \n alle Umbrüche?



<< >> 4 Einträge, 1 Seite
perlcharly
 2007-01-05 20:59
#72911 #72911
User since
2007-01-05
11 Artikel
BenutzerIn
[default_avatar]
Hi, ich hatte mal für ein Skript einige Passagen aus anderen Freeware-Skripts übernommen.
Dort tauchten dann auch Anweisungen auf, um Zeilenumbrüche zu transformieren, z.B.

$content =~ s/\cM\n/\n/g;
$content =~ s/\n\cM/\n/g;
$content =~ s/\cM/\n/g;

Meine Frage ist nun:
Hat "\cM" heute überhaupt noch eine Funktion?

In der Perl-Doku finde ich dazu nur sehr wenig verständliche Hinweise, etwa derart, dass Zeilenumbrüche in einzelnen Betriebssystemen und Servern auch als \cM dargestellt werden können.
Anders gefragt: Wenn ich aus einem Text alle Zeilenbrüchenumbrüche rausschmeißen will, reicht dazu die Anweisung aus:
$text =~ s/\n+//gm;

Oder muss ich das obskure \cM unter bestimmten Bedingungen (Server, Betriebssystem) doch berücksichtigen?
topeg
 2007-01-05 21:59
#72912 #72912
User since
2006-07-10
2611 Artikel
BenutzerIn

user image
Allso "\cM" entspricht "\012" oder "\r" allso "Carriage-Return"
"\cP" entspräche "\015" oder "\n" allso "Linefeed"
Es gibt nun vier verschidene Arten von Zeilenumbrüchen;
"\r\n" - Wird von Windows benutzt (ebenso TOS, DOS, CPM)
"\r" - Auf älteren MacOS üblich
"\n\r" Amiga (Beos glabe ich auch)
"\n" Auf allen unixuiden Systemen benutzt.

Nun ist es günstig alle verschidenen Umbrüche auf einen Nenner zu bringen:
Code: (dl )
$content =~ s/\012?\015|\015?\012/\n/gs;
esskar
 2007-01-06 08:51
#72913 #72913
User since
2003-08-04
7321 Artikel
ModeratorIn

user image
wenn du mit windows dateien auf einem linux system arbeitest, musst du eben aufpassen.
Dubu
 2007-01-19 15:44
#72914 #72914
User since
2003-08-04
2145 Artikel
ModeratorIn + EditorIn

user image
Ein paar Korrekturen:

[quote=topeg,05.01.2007, 20:59]Allso "\cM" entspricht "\012" oder "\r" allso "Carriage-Return"
"\cP" entspräche "\015" oder "\n" allso "Linefeed"
[/quote]

Hier bist du wohl etwas mit Dezimal- und Oktaldarstellung durcheinander geraten.
"\cM" (Carriage Return) ist "\015" (oktal) oder chr(13) (dezimal) oder "\x0D" (hexadezimal) oder "\r".
"\cJ" (Line Feed) ist "\012" (oktal) oder chr(10) (dezimal) oder "\x0A" (hexadezimal).

"\n" ist die Perl-interne Darstellung für ein Newline. Es wird intern meist als "\012", als Line Feed, abgespeichert (außer beim alten MacPerl, wo es intern ein Carriage Return war).

Quote
Es gibt nun vier verschidene Arten von Zeilenumbrüchen;
"\r\n" - Wird von Windows benutzt (ebenso TOS, DOS, CPM)
"\r" - Auf älteren MacOS üblich
"\n\r" Amiga (Beos glabe ich auch)
"\n" Auf allen unixuiden Systemen benutzt.


Wenn man unter Windows eine DOS/Windows-Textdatei im Textmodus einliest oder schreibt, dann ist ein Zeilenumbruch in Perl ein "\n", auch wenn in der Datei die Folge "\015\012" steht!
Es findet eine automatische Konvertierung zwischen intern "\012" und extern "\015\012" statt. Unter unixoiden Systemen ist die interne und externe Darstellung ohnehin gleich. Wenn man also Dateien des "eigenen" Betriebssystems verarbeitet, macht Perl schon immer Das Richtige[tm].

Das Zeichen "\n" ist daher zwar immer ein Perl-interner Zeilenumbruch, aber beim Parsen externer Daten mehrdeutig (abhängig von Betriebssystem und Text-/Binärmodus). Wenn man klar machen möchte, welcher Zeichencode gemeint ist (Carriage Return, Line Feed oder eine Kombination), sollte man eine eindeutige Schreibweise wie "\012" oder "\cJ" benutzen.

Aufpassen muss man, wenn man Dateien von fremden Betriebssystemen oder im Binärmodus verarbeitet.

Quote
Nun ist es günstig alle verschidenen Umbrüche auf einen Nenner zu bringen:
Code: (dl )
$content =~ s/\012?\015|\015?\012/\n/gs;


Sofern man wirklich ein "\n" haben möchte (abhängig davon, was man mit $content im Weiteren macht).
<< >> 4 Einträge, 1 Seite



View all threads created 2007-01-05 20:59.