2009-12-02 8 views
27

Ich habe eine Zeichenfolge in Ruby, s (sagen wir), die eine der Standard-Zeilenenden (\n, \r\n, \r) haben kann. Ich möchte alle diese zu \n s konvertieren. Was ist der beste Weg?Normalisieren Zeilenenden in Ruby

Dies scheint ein sehr häufiges Problem, aber es gibt nicht viel Dokumentation darüber. Offensichtlich gibt es einfache grobe Lösungen, aber ist da etwas eingebaut, um damit umzugehen?

Elegante, idiomatische Ruby-Lösungen sind die besten.

EDIT: erkannt, dass ^M und \r sind gleich. Aber es gibt immer noch drei Fälle. (Siehe wikipedia.)

Antwort

35

Beste ist gerade die beiden Fälle zu behandeln, die Sie speziell und nicht ändern wollen versuchen, zu klug zu bekommen:

s.gsub /\r\n?/, "\n" 
+1

Zwei Dinge: Sie müssen \ r \ n zuerst in die Regex setzen oder sonst wird es nie übereinstimmen (weil alle, die sonst b \ r \ n passen könnten, zuerst von \ r \ n verglichen werden). Und '\ n' == "\\ n", während das was du willst ist "\ n". – sepp2k

+0

Ändern Sie die einfachen Anführungszeichen in doppelte Anführungszeichen. Sonst funktioniert es nicht wie vorgesehen. –

+0

Es scheint, wir sind alle auf der gleichen Seite :) –

-8

Versuchen Sie, sie auf NetBeans IDE zu öffnen - Es fragte mich zuvor, auf einem der Projekte, die ich von anderswo geöffnet habe, wenn ich die Zeilenenden beheben wollte. Ich denke, es könnte auch eine Menüoption geben, aber das wäre das erste, was ich versuchen würde.

+2

Dank, aber dies ist nicht eine einmalige; Dies ist für die Verarbeitung von Daten in Ruby, keine Verarbeitung von Ruby-Dateien. – Peter

3

Ich denke, die sauberste Lösung, die einen regulären Ausdruck zu verwenden, wäre:

s.gsub! /\r\n?/, "\n" 
+0

oops, das hat einen Trap: doppelte Zeilenumbrüche wie '\ n \ n' werden' \ n'. – Peter

+0

Hoppla, danke, dass du darauf hingewiesen hast, aber Jleedev war ein bisschen schneller. –

29

Seit 1.9 Rubin können Sie String::encode mit :universal_newline => true verwenden alle neuen Linien in \n zu erhalten, während die Codierung unverändert bleibt:

s.encode(s.encoding, :universal_newline => true) 

Einmal in einem bekannten Newline-Status können Sie frei zurück in CRLF mit :crlf_newline konvertieren. zB: eine Datei unbekannt (möglicherweise gemischt) enden zu CRLF (zum Beispiel), lesen Sie es in Binär-Modus zu konvertieren, dann:

s.encode(s.encoding, :universal_newline => true).encode(s.encoding, :crlf_newline => true) 
+5

Sie müssen nicht die erste 's.encoding', eine einfache' scode (universal_newline: true) 'oder' s. encode (crlf_newline: true) 'macht den Trick. Das hat mir heute bei einem Projekt geholfen. – Donovan

+0

@Donovan - Sie sind _probably_ richtig, aber die Dokumentation sagt, dass die Version ohne eine explizite Kodierung in 'Encoding.default_internal' transkodiert, was möglicherweise nicht das ist, was Sie wollen. Meine Version behält konservativ Ihre gegenwärtige Kodierung bei. – Greg

+1

true und Sie machen einen guten Punkt, aber in den meisten Fällen ist die Standardeinstellung in Ordnung, das ist, was 'String.new' verwendet.Also, in meinem Fall (und ich könnte in den meisten Fällen argumentieren), wäre es überflüssig. – Donovan