Quelle est la méthode préférée pour supprimer les derniers n
caractères d'une chaîne?
À partir de Ruby 2.5, vous pouvez utiliser delete_suffix
ou delete_suffix!
pour y parvenir rapidement et de manière lisible.
Les docs sur les méthodes sont here .
Si vous savez ce qu'est le suffixe, c'est idiomatique (et je dirais même plus lisible que d'autres réponses ici):
'abc123'.delete_suffix('123') # => "abc"
'abc123'.delete_suffix!('123') # => "abc"
C'est même nettement plus rapide (presque 40% avec la méthode bang)) que la première réponse. Voici le résultat du même repère:
user system total real
chomp 0.949823 0.001025 0.950848 ( 0.951941)
range 1.874237 0.001472 1.875709 ( 1.876820)
delete_suffix 0.721699 0.000945 0.722644 ( 0.723410)
delete_suffix! 0.650042 0.000714 0.650756 ( 0.651332)
J'espère que cela est utile - notez que la méthode n'accepte pas actuellement les regex, donc si vous ne connaissez pas le suffixe, ce n'est pas viable pour le moment. Cependant, comme la réponse acceptée ( update: au moment de la rédaction de cet article ) dicte la même chose, j’ai pensé que cela pourrait être utile à certaines personnes.
irb> 'now is the time'[0...-4]
=> "now is the "
Si les caractères que vous souhaitez supprimer sont toujours les mêmes, alors considérez chomp
:
'abc123'.chomp('123') # => "abc"
Les avantages de chomp
sont les suivants: pas de comptage, et le code communique plus clairement ce qu'il fait.
Sans arguments, chomp
supprime les fins de ligne DOS ou Unix, si l'une ou l'autre est présente:
"abc\n".chomp # => "abc"
"abc\r\n".chomp # => "abc"
Parmi les commentaires, il y avait une question de la vitesse d'utilisation de #chomp
par rapport à l'utilisation d'une plage. Voici un repère comparant les 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 référence (avec CRuby 2.13p242):
Rehearsal -----------------------------------------
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)
Donc, chomp est plus rapide que d'utiliser une plage, d'environ 22%.
str = str[0...-n]
Je suggérerais chop
. Je pense que cela a été mentionné dans l'un des commentaires mais sans liens ni explications, alors voici pourquoi je pense que c'est mieux:
Il supprime simplement le dernier caractère d'une chaîne et vous n'avez pas à spécifier de valeurs pour que cela se produise.
Si vous devez supprimer plusieurs caractères, alors chomp
est votre meilleur choix. C’est ce que les ruby docs ont à dire à 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. L'application de hachage à une chaîne vide renvoie une chaîne vide. String # chomp est souvent une alternative plus sûre, car la chaîne reste 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 chaîne simple, par exemple le s
pour rendre le mot singulier.
name = "my text"
x.times do name.chop! end
Ici dans la console:
>name = "Nabucodonosor"
=> "Nabucodonosor"
> 7.times do name.chop! end
=> 7
> name
=> "Nabuco"
Supprimer les derniers n
caractères revient à conserver les premiers _length - n
_ caractères.
Le support actif inclut les méthodes String#first
et String#last
qui constituent un moyen pratique de conserver ou de supprimer les premiers/derniers caractères n
:
_require 'active_support/core_ext/string/access'
"foobarbaz".first(3) # => "foo"
"foobarbaz".first(-3) # => "foobar"
"foobarbaz".last(3) # => "baz"
"foobarbaz".last(-3) # => "barbaz"
_
si vous utilisez Rails, essayez:
"my_string".last(2) # => "ng"
[ÉDITÉ]
Pour obtenir la chaîne SANS les 2 derniers caractères:
n = "my_string".size
"my_string"[0..n-3] # => "my_stri"
Remarque: le dernier caractère de la chaîne est à n-1. Donc, pour supprimer les 2 derniers, nous utilisons n-3.
Vous pouvez toujours utiliser quelque chose comme
"string".sub!(/.{X}$/,'')
Où X
est le nombre de caractères à supprimer.
Ou en assignant/utilisant le résultat:
myvar = "string"[0..-X]
où X
est le nombre de caractères plus un à supprimer.
Découvrez la méthode slice()
:
Si vous êtes en mesure de créer des méthodes de classe et que vous voulez supprimer les caractères, essayez ceci:
class String
def chop_multiple(amount)
amount.times.inject([self, '']){ |(s, r)| [s.chop, r.prepend(s[-1])] }
end
end
hello, world = "hello world".chop_multiple 5
hello #=> 'hello '
world #=> 'world'
Utiliser regex:
str = 'string'
n = 2 #to remove last n characters
str[/\A.{#{str.size-n}}/] #=> "stri"