2008-11-13 10 views
65

Je pensais que ce code fonctionnerait, mais l'expression régulière ne correspond jamais au \ r \ n. J'ai regardé les données que je suis en train de lire dans un éditeur hexadécimal et vérifié qu'il y a vraiment un hexagone D et un hexagone A dans le fichier.Comment supprimer les retours chariot avec Ruby?

J'ai également essayé les expressions régulières/\ xD \ xA/m et/\ x0D \ x0A/m mais elles ne correspondaient pas non plus.

Ceci est mon code en ce moment:

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

En plus des alternatives, il serait bon de savoir ce que je fais mal (pour faciliter un apprentissage de ma part). :)

Répondre

23

Qu'est-ce que vous obtenez lorsque vous faites puts lines? Cela vous donnera une idée. Par défaut, File.open ouvre le fichier en mode texte, de sorte que vos \r\n caractères seront automatiquement convertis en \n. Peut-être que c'est la raison lines sont toujours égal à lines2. Pour éviter Ruby de la ligne se termine l'analyse syntaxique utiliser le mode rb:

C:\> copy con lala.txt 
a 
file 
with 
many 
lines 
^Z 

C:\> irb 
irb(main):001:0> text = File.open('lala.txt').read 
=> "a\nfile\nwith\nmany\nlines\n" 
irb(main):002:0> bin = File.open('lala.txt', 'rb').read 
=> "a\r\nfile\r\nwith\r\nmany\r\nlines\r\n" 
irb(main):003:0> 

Mais de votre question et le code je vois que vous avez simplement besoin d'ouvrir le fichier avec le modificateur par défaut. Vous n'avez besoin d'aucune conversion et pouvez utiliser le raccourci File.read.

+2

Il y a une réponse avec plus de upvotes orientés vers le "Strip newlines" plus bas: http://stackoverflow.com/a/7095275/403234 – yas4891

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

Cela dépouilleront les onglets et les espaces, qui peuvent ne pas être ce que l'utilisateur veut. – Doug

6

Pourquoi pas?

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> 

Ou ...

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> 
+0

aussi, j'ai vérifié: "\ r \ n"! = "\ N". Donc, il semble que le code des affiches originales est juste. – rampion

33

En général, quand je traite stripping \ r ou \ n, je vais chercher à la fois en faisant quelque chose comme

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

J'ai trouvé que selon la façon dont les données ont été sauvegardées (le système d'exploitation utilisé, l'éditeur utilisé, la relation de Jupiter à Io à ce moment-là) il peut ou peut ne pas être le retour à la ligne après le retour chariot. Cela semble bizarre que vous voyiez les deux personnages en mode hexadécimal. J'espère que cela t'aides.

149

Utilisez String#strip

Renvoie une copie de str avec les espaces avant et enlevé.

par exemple

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


En utilisant gsub

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

Il ne va pas filtrer les nouvelles lignes au milieu du texte: "line1 \ n line2 ".strip # =>" line1 \ n line2 " – ndrix

+0

Si utilisé dans un appel' each_line', cela n'a pas d'importance. –

+5

Suppression de tous les espaces environnants! = Suppression des retours chariot –

2

Pourquoi ne pas lire le fichier en mode texte, plutôt que le mode binaire?

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

Merci beaucoup! Ça sauve ma journée! – Rubyrider

+2

Ceci remplace tout caractère d'espace, et pas seulement CR/LFs – hoffmanc

1

Vous pouvez utiliser ceci:

my_string.strip.gsub(/\s+/, ' ') 
+1

Essentiellement la même réponse que [this] (http://stackoverflow.com/a/8891341/1735262) ​​ci-dessus. – iamnotmaynard

12

Si vous utilisez Rails, il existe une méthode squish

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

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

+0

c'est un bon conseil! – bryanus

+0

Pour les utilisateurs non-Rails, il est implémenté sous la forme 'str.gsub (/ [[: space:]] + /, '') .strip' – sobstel

0

Je pense que votre regex est presque terminée - voici ce que je ferais:

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

Dans ce qui précède, j'ai mis \ r \ n dans une classe (de cette façon, peu importe l'ordre dans lequel ils pourraient apparaître) et ajouté le qualificatif "+" (de sorte que "\ r \ n \ r \ n \ r \ n" soit aussi identique une fois, et l'ensemble chose remplacée par "\ n")

0

Juste une autre variante:

lines.delete(" \n") 
Questions connexes