Was ist die bevorzugte Methode zum Entfernen der letzten n
Zeichen aus einer Zeichenfolge?
Was ist die bevorzugte Methode zum Entfernen der letzten n
Zeichen aus einer Zeichenfolge?
Antworten:
Ab Ruby 2.5 können Sie dies schnell und lesbar verwenden delete_suffix
oder delete_suffix!
erreichen.
Die Dokumente zu den Methoden finden Sie hier .
Wenn Sie wissen, was das Suffix ist, ist dies idiomatisch (und ich würde argumentieren, noch besser lesbar als andere Antworten hier):
'abc123'.delete_suffix('123') # => "abc"
'abc123'.delete_suffix!('123') # => "abc"
Es ist sogar deutlich schneller (fast 40% mit der Bang-Methode) als die Top-Antwort. Hier ist das Ergebnis des gleichen Benchmarks:
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)
Ich hoffe, dies ist nützlich - beachten Sie, dass die Methode derzeit keinen regulären Ausdruck akzeptiert. Wenn Sie das Suffix nicht kennen, ist es vorerst nicht realisierbar. Da die akzeptierte Antwort ( Update: zum Zeitpunkt des Schreibens ) dasselbe vorschreibt, dachte ich, dass dies für einige Leute nützlich sein könnte.
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]
nicht[0..-4]
Wenn die Zeichen, die Sie entfernen möchten, immer dieselben Zeichen sind, beachten Sie Folgendes chomp
:
'abc123'.chomp('123') # => "abc"
Die Vorteile von chomp
sind: kein Zählen, und der Code kommuniziert klarer, was er tut.
Entfernt ohne Argumente chomp
das DOS- oder Unix-Zeilenende, falls eines der beiden vorhanden ist:
"abc\n".chomp # => "abc"
"abc\r\n".chomp # => "abc"
Aus den Kommentaren ging die Frage nach der Geschwindigkeit der Verwendung im #chomp
Vergleich zur Verwendung eines Bereichs hervor. Hier ist ein Benchmark, der die beiden vergleicht:
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
Benchmark-Ergebnisse (mit 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)
Chomp ist also um ~ 22% schneller als die Verwendung eines Bereichs.
chomp!()
damit direkt auf den String einwirken.
str = str[0...-n]
ich würde vorschlagen chop
. Ich denke, es wurde in einem der Kommentare erwähnt, aber ohne Links oder Erklärungen. Deshalb denke ich, dass es besser ist:
Es wird einfach das letzte Zeichen aus einer Zeichenfolge entfernt, und Sie müssen dafür keine Werte angeben.
Wenn Sie mehr als einen Charakter entfernen müssen, chomp
ist dies die beste Wahl. Dies ist, was die Ruby-Dokumente zu sagen haben chop
:
Gibt einen neuen String zurück, bei dem das letzte Zeichen entfernt wurde. Wenn die Zeichenfolge mit \ r \ n endet, werden beide Zeichen entfernt. Wenn Sie chop auf eine leere Zeichenfolge anwenden, wird eine leere Zeichenfolge zurückgegeben. String # chomp ist oft eine sicherere Alternative, da der String unverändert bleibt, wenn er nicht in einem Datensatztrennzeichen endet.
Obwohl dies hauptsächlich zum Entfernen von Trennzeichen verwendet wird, wie \r\n
ich es verwendet habe, um das letzte Zeichen aus einer einfachen Zeichenfolge zu entfernen, z. B. s
um das Wort singulär zu machen.
Das Löschen der letzten n
Zeichen entspricht dem Beibehalten der ersten length - n
Zeichen.
Active Support enthält String#first
und String#last
Methoden, die eine bequeme Möglichkeit bieten, die ersten / letzten n
Zeichen beizubehalten oder zu löschen :
require 'active_support/core_ext/string/access'
"foobarbaz".first(3) # => "foo"
"foobarbaz".first(-3) # => "foobar"
"foobarbaz".last(3) # => "baz"
"foobarbaz".last(-3) # => "barbaz"
Wenn Sie Schienen verwenden, versuchen Sie:
"my_string".last(2) # => "ng"
[BEARBEITET]
So erhalten Sie die Zeichenfolge OHNE die letzten 2 Zeichen:
n = "my_string".size
"my_string"[0..n-3] # => "my_stri"
Hinweis: Das letzte Zeichenfolgenzeichen ist bei n-1. Um die letzten 2 zu entfernen, verwenden wir n-3.
Sie können immer so etwas verwenden
"string".sub!(/.{X}$/,'')
Wo X
ist die Anzahl der zu entfernenden Zeichen?
Oder mit Zuweisen / Verwenden des Ergebnisses:
myvar = "string"[0..-X]
Wo X
ist die Anzahl der Zeichen plus eins zu entfernen.
Überprüfen Sie die slice()
Methode:
Wenn Sie mit dem Erstellen von Klassenmethoden einverstanden sind und die Zeichen, die Sie abhacken, möchten, versuchen Sie Folgendes:
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'
Regex verwenden:
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
Ruby 2.5 verwenden. Mehr Infos hier .