Wie entferne ich Wagenrückläufe mit Ruby?


75

Ich dachte, dieser Code würde funktionieren, aber der reguläre Ausdruck stimmt nie mit dem \ r \ n überein. Ich habe die Daten, die ich lese, in einem Hex-Editor angezeigt und überprüft, ob die Datei wirklich ein Hex-D- und ein Hex-A-Muster enthält.

Ich habe auch die regulären Ausdrücke / \ xD \ xA / m und / \ x0D \ x0A / m ausprobiert, aber sie stimmten auch nicht überein.

Dies ist jetzt mein Code:

   lines2 = lines.gsub( /\r\n/m, "\n" )
   if ( lines == lines2 )
       print "still the same\n"
   else
       print "made the change\n"
   end

Zusätzlich zu Alternativen wäre es schön zu wissen, was ich falsch mache (um meinerseits das Lernen zu erleichtern). :) :)

Antworten:


23

Was bekommen Sie, wenn Sie tun puts lines? Das gibt Ihnen einen Hinweis.

Standardmäßig File.openwird die Datei im Textmodus geöffnet, sodass Ihre \r\nZeichen automatisch in konvertiert werden \n. Vielleicht ist das der Grund, warum sie linesimmer gleich sind lines2. Verwenden Sie den folgenden rbModus, um zu verhindern, dass Ruby die Zeilenenden analysiert :

C: \> copy con lala.txt
ein
Datei
mit
viele
Linien
^ Z.

C: \> irb
irb (main): 001: 0> text = File.open ('lala.txt'). read
=> "a \ nDatei \ nmit \ nVielen \ nZeilen \ n"
irb (main): 002: 0> bin = File.open ('lala.txt', 'rb'). read
=> "a \ r \ nDatei \ r \ nmit \ r \ nviel \ r \ nLinien \ r \ n"
irb (main): 003: 0>

Aus Ihrer Frage und Ihrem Code geht jedoch hervor, dass Sie die Datei lediglich mit dem Standardmodifikator öffnen müssen. Sie benötigen keine Konvertierung und können die kürzere verwenden File.read.


2
Es gibt eine Antwort mit mehr positiven Stimmen, die auf die "Strip Newlines" weiter unten ausgerichtet sind: stackoverflow.com/a/7095275/403234
yas4891

167

Verwenden Sie String # strip

Gibt eine Kopie von str zurück, wobei führende und nachfolgende Leerzeichen entfernt wurden.

z.B

"    hello    ".strip   #=> "hello"   
"\tgoodbye\r\n".strip   #=> "goodbye"

Mit gsub

string = string.gsub(/\r/," ")
string = string.gsub(/\n/," ")

5
Es werden keine Zeilenumbrüche in der Mitte des Textes gefiltert: "line1 \ n line2" .strip # => "line1 \ n line2"
ndrix

Wenn es innerhalb eines each_lineAnrufs verwendet wird, spielt das keine Rolle.
Ian Vaughan

9
Entfernen aller umgebenden Leerzeichen! = Entfernen von Wagenrückläufen
Barry Kelly

35

Wenn ich mich mit Strippen oder \ n beschäftige, suche ich im Allgemeinen nach beidem, indem ich so etwas mache

lines.gsub(/\r\n?/, "\n");

Ich habe festgestellt, dass je nachdem, wie die Daten gespeichert wurden (das verwendete Betriebssystem, der verwendete Editor, Jupiters Beziehung zu Io zu der Zeit), nach dem Wagenrücklauf möglicherweise die neue Zeile vorhanden ist oder nicht. Es scheint seltsam, dass Sie beide Zeichen im Hex-Modus sehen. Hoffe das hilft.


21

Wenn Sie Rails verwenden, gibt es eine squishMethode

"\tgoodbye\r\n".squish => "goodbye"

"\tgood \t\r\nbye\r\n".squish => "good bye"


Das ist ein toller Tipp!
Bryanus

2
Für Nicht-Rails-Benutzer ist es implementiert alsstr.gsub(/[[:space:]]+/, ' ').strip
sobstel

17
modified_string = string.gsub(/\s+/, ' ').strip

Danke vielmals! Es rettet meinen Tag!
Rubyrider

2
Dies ersetzt alle Leerzeichen, nicht nur CR / LFs
hoffmanc

15
lines2 = lines.split.join("\n")

4
Dadurch werden auch Tabulatoren und Leerzeichen entfernt, was möglicherweise nicht den Wünschen des Benutzers entspricht.
Doug


6

Wie wäre es mit folgendem?

irb(main):003:0> my_string = "Some text with a carriage return \r"
=> "Some text with a carriage return \r"
irb(main):004:0> my_string.gsub(/\r/,"")
=> "Some text with a carriage return "
irb(main):005:0>

Oder...

irb(main):007:0> my_string = "Some text with a carriage return \r\n"
=> "Some text with a carriage return \r\n"
irb(main):008:0> my_string.gsub(/\r\n/,"\n")
=> "Some text with a carriage return \n"
irb(main):009:0>

Außerdem habe ich Folgendes überprüft: "\ r \ n"! = "\ n". Es sieht also so aus, als ob der ursprüngliche Postercode richtig ist.
Rampion

4

Ich denke, Ihre Regex ist fast vollständig - hier ist, was ich tun würde:

lines2 = lines.gsub(/[\r\n]+/m, "\n")

Oben habe ich \ r und \ n in eine Klasse eingefügt (auf diese Weise spielt es keine Rolle, in welcher Reihenfolge sie erscheinen) und das Qualifikationsmerkmal "+" hinzugefügt (so dass "\ r \ n \ r \ n" \ r \ n "würde auch einmal übereinstimmen, und das Ganze durch" \ n "ersetzt)






0
def dos2unix(input)
  input.each_byte.map { |c| c.chr unless c == 13 }.join
end

remove_all_the_carriage_returns = dos2unix(some_blob)
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.