Quelle est la meilleure façon de supprimer les derniers n
caractères d'une chaîne?
Quelle est la meilleure façon de supprimer les derniers n
caractères d'une chaîne?
Réponses:
Depuis Ruby 2.5, vous pouvez utiliser delete_suffix
ou delete_suffix!
pour y parvenir de manière rapide et lisible.
Les documents sur les méthodes sont ici .
Si vous savez quel est le suffixe, c'est idiomatique (et je dirais, encore plus lisible que les autres réponses ici):
'abc123'.delete_suffix('123') # => "abc"
'abc123'.delete_suffix!('123') # => "abc"
C'est encore beaucoup plus rapide (près de 40% avec la méthode du bang) que la meilleure réponse. Voici le résultat du même benchmark:
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 une expression régulière, donc si vous ne connaissez pas le suffixe, il n'est pas viable pour le moment. Cependant, comme la réponse acceptée ( mise à jour: au moment de la rédaction ) l'impose, j'ai pensé que cela pourrait être utile à certaines personnes.
What is the preferred way of removing the last n characters from a string?
irb> 'now is the time'[0...-4]
=> "now is the "
[0...-4]
pas[0..-4]
Si les caractères que vous souhaitez supprimer sont toujours les mêmes, envisagez chomp
:
'abc123'.chomp('123') # => "abc"
Les avantages de chomp
sont: pas de comptage, et le code communique plus clairement ce qu'il fait.
Sans aucun argument, chomp
supprime la fin de ligne DOS ou Unix, si l'un ou l'autre est présent:
"abc\n".chomp # => "abc"
"abc\r\n".chomp # => "abc"
D'après les commentaires, il y avait une question de la vitesse d'utilisation #chomp
par rapport à l'utilisation d'une plage. Voici une référence 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 (en utilisant 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)
Le chomp est donc plus rapide que l'utilisation d'une plage, de ~ 22%.
chomp!()
pour agir sur la chaîne en place.
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 besoin de spécifier de valeurs pour que cela se produise.
Si vous devez supprimer plusieurs personnages, chomp
c'est votre meilleur pari. Voici ce que les docs rubis ont à dire sur 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 hacher à une chaîne vide renvoie une chaîne vide. La chaîne # chomp est souvent une alternative plus sûre, car elle laisse la chaîne inchangée si elle ne se termine pas dans 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 s
pour rendre le mot singulier.
La suppression des derniers n
caractères revient à conserver les premiers length - n
caractères.
Le soutien actif comprend String#first
et des String#last
méthodes qui fournissent un moyen pratique de conserver ou de laisser tomber les premiers / derniers n
caractères:
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 des 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 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 affectant / utilisant le résultat:
myvar = "string"[0..-X]
où X
est le nombre de caractères plus un à supprimer.
Découvrez la slice()
méthode:
Si vous êtes d'accord avec la création de méthodes de classe et voulez les caractères que vous coupez, 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'
Utilisation de regex:
str = 'string'
n = 2 #to remove last n characters
str[/\A.{#{str.size-n}}/] #=> "stri"
x = "my_test"
last_char = x.split('').last
delete_suffix
partir de Ruby 2.5. Plus d'infos ici .