301 votes

Ruby, supprimer les derniers N caractères d'une chaîne de caractères?

Quelle est la meilleure façon de supprimer les derniers n caractères d'une chaîne de caractères ?

0 votes

Si vous connaissez le suffixe (la réponse principale suggère que beaucoup viennent ici à la recherche de cela), vous pouvez utiliser delete_suffix à partir de Ruby 2.5. Plus d'informations ici.

354voto

DigitalRoss Points 80400
irb> 'now is the time'[0...-4]
=> "maintenant c'est "

9 votes

Notez que cela ne fonctionne qu'en Ruby 1.9. En Ruby 1.8, cela supprimera les derniers octets, et non les derniers caractères.

2 votes

Mais il voulait probablement dire "octets" s'il utilise 1.8.x.

4 votes

Cela fonctionne, mais je trouve que 'abc123'.chomp('123') est deux fois plus rapide pour les chaînes courtes et très longues. (Ruby 2.0.0-p247) Est-ce que quelqu'un peut confirmer cela ?

275voto

Wayne Conrad Points 31052

Si les caractères que vous souhaitez supprimer sont toujours les mêmes, envisagez d'utiliser chomp :

'abc123'.chomp('123')    # => "abc"

Les avantages de chomp sont : pas de comptage, et le code communique plus clairement ce qu'il fait.

Sans argument, chomp supprime le saut de ligne DOS ou Unix, s'il est présent :

"abc\n".chomp      # => "abc"
"abc\r\n".chomp    # => "abc"

D'après les commentaires, il y avait une question sur la vitesse d'utilisation de #chomp par rapport à l'utilisation d'une plage. Voici une comparaison de performance des deux :

require 'benchmark'

S = 'asdfghjkl'
SL = S.length
T = 10_000
A = 1_000.times.map { |n| "#{n}#{S}" }

GC.disable

Benchmark.bmbm do |x|
  x.report('chomp') { T.times { A.each { |s| s.chomp(S) } } }
  x.report('range') { T.times { A.each { |s| s[0...-SL] } } }
end

Résultats de la comparaison des performances (en utilisant CRuby 2.13p242) :

Répétition -----------------------------------------
chomp   1.540000   0.040000   1.580000 (  1.587908)
range   1.810000   0.200000   2.010000 (  2.011846)
-------------------------------- total: 3.590000sec

            user     system      total        real
chomp   1.550000   0.070000   1.620000 (  1.610362)
range   1.970000   0.170000   2.140000 (  2.146682)

Ainsi, chomp est plus rapide que l'utilisation d'une plage, d'environ 22%.

5 votes

Hacher est également une option. Il est moins pointilleux sur ce qui est enlevé.

0 votes

Algorithmiquement, n'est-ce pas quelque chose comme [0..-#] serait plus rapide? un chomp doit analyser une chaîne à la recherche de correspondances. Exclure un numéro de caractère de fin ne le fait pas.

0 votes

Où serait l'endroit le plus approprié pour mes résultats de référence?

65voto

Nakilon Points 11635
str = str[0..-1-n]

Contrairement au [0...-n], cela gère le cas où n=0.

5 votes

Notez que cela fonctionne uniquement en Ruby 1.9. En Ruby 1.8, cela supprimera les derniers octets, et non les derniers caractères.

5 votes

C'est mieux que la réponse choisie, puisque 3 points (...) est plus facile à mémoriser puisque -n signifie retirer n caractères de la fin de la chaîne.

0 votes

Aussi "abcd"[0..-2] #=> "abc" tandis que "abcd"[0...-2] #=> "ab". À mon avis, l'option de plage 3 points donne un code plus explicite.

33voto

kakubei Points 1526

Je suggérerais chop. Je pense que cela a été mentionné dans l'un des commentaires mais sans liens ou explications, donc voici pourquoi je pense que c'est mieux :

Il suffit de supprimer le dernier caractère d'une chaîne et vous n'avez pas besoin de spécifier de valeurs pour que cela se produise.

Si vous avez besoin de supprimer plus d'un caractère, alors chomp est votre meilleur choix. Voici ce que disent les docs de Ruby à propos de chop :

Renvoie une nouvelle chaîne avec le dernier caractère supprimé. Si la chaîne se termine par \r\n, les deux caractères sont supprimés. Appliquer chop à une chaîne vide renvoie une chaîne vide. String#chomp est souvent une alternative plus sûre, car elle laisse la chaîne inchangée si elle ne se termine pas par un séparateur d'enregistrement.

Bien que cela soit principalement utilisé pour supprimer des séparateurs tels que \r\n, je l'ai utilisé pour supprimer le dernier caractère d'une simple chaîne, par exemple le s pour rendre le mot au singulier.

1 votes

Ne supprimerait-il pas simplement ce dernier caractère unique? La question concerne les "caractères" au pluriel

1 votes

Oui, vous avez raison, mais chomp('chars') supprimera le dernier 'chars'. Il n'était pas clair pour moi si l'OP voulait des caractères spécifiques ou simplement N caractères.

0 votes

Oui, c'est la réponse, seulement lorsque vous voulez supprimer un seul caractère (ce qui était le cas pour moi cependant).

30voto

joscas Points 2536
nom = "mon texte"
x.times do nom.chop! end

Voici dans la console:

>nom = "Nabucodonosor"
 => "Nabucodonosor" 
> 7.times do nom.chop! end
 => 7 
> nom
 => "Nabuco"

0 votes

Est-ce efficace? Semble valoir la peine d'être comparé à d'autres réponses :)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X