webentwicklung-frage-antwort-db.com.de

Ruby, letzte N Zeichen aus einer Zeichenkette entfernen?

Was ist die bevorzugte Methode, um die letzten n Zeichen aus einer Zeichenfolge zu entfernen?

239
JP Silvashy

Ruby 2.5+

Ab Ruby 2.5 können Sie delete_suffix oder delete_suffix! um dies schnell und lesbar zu erreichen.

Die Dokumente zu den Methoden sind hier .

Wenn Sie wissen, was das Suffix ist, ist dies idiomatisch (und ich würde argumentieren, noch lesbarer als andere Antworten hier):

'abc123'.delete_suffix('123')     # => "abc"
'abc123'.delete_suffix!('123')    # => "abc"

Es ist sogar bedeutend schneller (fast 40% mit der Knallmethode) als die beste 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 keine regulären Ausdrücke akzeptiert. Wenn Sie also das Suffix nicht kennen, ist dies vorerst nicht möglich. Da jedoch die akzeptierte Antwort ( update: zum Zeitpunkt des Schreibens ) dasselbe vorschreibt, dachte ich, dass dies für einige Leute nützlich sein könnte.

8
SRack
irb> 'now is the time'[0...-4]
=> "now is the "
303
DigitalRoss

Wenn die Zeichen, die Sie entfernen möchten, immer dieselben Zeichen sind, berücksichtigen Sie chomp:

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

Die Vorteile von chomp sind: Keine Zählung, und der Code kommuniziert klarer, was er tut.

Ohne Argumente entfernt chomp das DOS- oder Unix-Zeilenende, falls eines vorhanden ist:

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

Aus den Kommentaren ging hervor, wie schnell #chomp versus Verwendung eines Bereichs. Hier ist ein Vergleich der beiden Benchmarks:

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.

261
Wayne Conrad
str = str[0...-n]
53
Nakilon

Ich würde chop vorschlagen. 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 keine Werte angeben, damit dies geschieht.

Wenn Sie mehr als ein Zeichen entfernen müssen, ist chomp Ihre beste Wahl. Dies ist, was die Ruby docs über chop zu sagen haben:

Gibt eine neue Zeichenfolge mit dem letzten entfernten Zeichen zurück. 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 häufig eine sicherere Alternative, da der String unverändert bleibt, wenn er nicht in einem Datensatztrennzeichen endet.

Obwohl dies hauptsächlich verwendet wird, um Trennzeichen wie \r\n Zu entfernen, habe ich es verwendet, um das letzte Zeichen aus einer einfachen Zeichenfolge zu entfernen, zum Beispiel das s, um das Wort singulär zu machen.

29
kakubei
name = "my text"
x.times do name.chop! end

Hier in der Konsole:

>name = "Nabucodonosor"
 => "Nabucodonosor" 
> 7.times do name.chop! end
 => 7 
> name
 => "Nabuco" 
29
joscas

Das Löschen der letzten n Zeichen entspricht dem Löschen der ersten length - n Figuren.

Aktive Unterstützung umfasst String#first und String#last Methoden, mit denen die ersten/letzten n Zeichen bequem beibehalten oder gelöscht werden können:

require 'active_support/core_ext/string/access'

"foobarbaz".first(3)  # => "foo"
"foobarbaz".first(-3) # => "foobar"
"foobarbaz".last(3)   # => "baz"
"foobarbaz".last(-3)  # => "barbaz"
13
chocolateboy

wenn Sie Rails verwenden, versuchen Sie Folgendes:

"my_string".last(2) # => "ng"

[EDITED]

So erhalten Sie die Zeichenfolge OHNE die letzten 2 Zeichen:

n = "my_string".size
"my_string"[0..n-3] # => "my_stri"

Hinweis: Die letzte Zeichenfolge befindet sich bei n-1. Um also die letzten 2 zu entfernen, verwenden wir n-3.

7
Guihen

Sie können immer so etwas verwenden

 "string".sub!(/.{X}$/,'')

Wobei X die Anzahl der zu entfernenden Zeichen ist.

Oder mit dem Zuweisen/Verwenden des Ergebnisses:

myvar = "string"[0..-X]

dabei ist X die Anzahl der zu entfernenden Zeichen plus eins.

3
Zsolt Botykai

Schauen Sie sich die Methode slice() an:

http://Ruby-doc.org/core-2.5.0/String.html#method-i-slice

3
Cody Caughlan

Wenn Sie mit der Erstellung von Klassenmethoden zufrieden 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'
1
Ben Aubin

Regex verwenden:

str = 'string'
n = 2  #to remove last n characters

str[/\A.{#{str.size-n}}/] #=> "stri"
0
Sagar Pandya