web-dev-qa-db-fra.com

Fractionner sur différentes nouvelles lignes

En ce moment, je fais un split sur une chaîne et je suppose que la nouvelle ligne de l'utilisateur est \r\n ainsi:

string.split(/\r\n/)

Ce que j'aimerais faire, c'est diviser sur \r\n ou juste \n.

Alors, quel serait le regex à partager sur l'un ou l'autre?

51
Shpigford

As-tu essayé /\r?\n/? Le ? fait le \r optionnel.

Exemple d'utilisation: http://rubular.com/r/1ZuihD0YfF

75
NickAldwin

Ruby a les méthodes String#each_line et String#lines

renvoie une énumération: http://www.Ruby-doc.org/core-1.9.3/String.html#method-i-each_line

renvoie un tableau: http://www.Ruby-doc.org/core-2.1.2/String.html#method-i-lines

Je ne l'ai pas testé par rapport à votre scénario, mais je parie que cela fonctionnera mieux que de choisir manuellement les caractères de nouvelle ligne.

17
23inhouse
# Split on \r\n or just \n
string.split( /\r?\n/ )

Bien que cela n'aide pas cette question (où vous avez besoin d'une expression régulière), notez que String#split Ne nécessite pas d'argument d'expression régulière. Votre code d'origine aurait également pu être string.split( "\r\n" ).

15
Phrogz
\n is for unix 
\r is for mac 
\r\n is for windows format

Pour être sûr pour les systèmes d'exploitation. Je ferais/\ r?\N |\r\n? /

"1\r2\n3\r\n4\n\n5\r\r6\r\n\r\n7".split(/\r?\n|\r\n?/)
=> ["1", "2", "3", "4", "", "5", "", "6", "", "7"]
4
Clark

L'opérateur d'alternance dans Ruby Regexp est le même que dans les expressions régulières standard: |

Donc, la solution évidente serait

/\r\n|\n/

ce qui est le même que

/\r?\n/

c'est-à-dire un \r facultatif suivi d'un \n obligatoire.

3
Jörg W Mittag

Peut-être faire une scission uniquement sur '\ n' et supprimer le '\ r' s'il existe?

1
SjoerdRavn

Êtes-vous en train de lire à partir d'un fichier ou d'un fichier standard?

Si vous lisez à partir d'un fichier et que le fichier est en mode texte plutôt qu'en mode binaire, ou si vous lisez en standard, vous n'aurez pas à traiter avec \r\n - ça ressemblera à \n.

C:\Documents and Settings\username>irb
irb(main):001:0> gets
foo
=> "foo\n"
1
Andrew Grimm

Une autre option consiste à utiliser String # chomp , qui gère également intelligemment les sauts de ligne.

Vous pouvez accomplir ce que vous recherchez avec quelque chose comme:

lines = string.lines.map(&:chomp)

Ou si vous avez affaire à quelque chose d'assez grand pour que l'utilisation de la mémoire soit un problème:

<string|io>.each_line do |line|
  line.chomp!
  #  do work..
end

Les performances ne sont pas toujours la chose la plus importante lors de la résolution de ce type de problème, mais il convient de noter que la solution chomp est également un peu plus rapide que l'utilisation d'une expression régulière.

Sur ma machine (i7, Ruby 2.1.9):

Warming up --------------------------------------
           map/chomp    14.715k i/100ms
  split custom regex    12.383k i/100ms
Calculating -------------------------------------
           map/chomp    158.590k (± 4.4%) i/s -    794.610k in   5.020908s
  split custom regex    128.722k (± 5.1%) i/s -    643.916k in   5.016150s
0
Matt Sanders