Wie lösche ich bestimmte Zeichen aus einer Zeichenfolge in Ruby?

82

Ich habe mehrere Zeichenfolgen, die so aussehen:

"((String1))"

Sie sind alle unterschiedlich lang. Wie kann ich die Klammern aus all diesen Zeichenfolgen in einer Schleife entfernen?

Cristiano
quelle
2
Klammern entfernen oder die ersten beiden und letzten beiden Zeichen aus einer "zufälligen" Zeichenfolge entfernen? (Eigentlich zufällig?)
Reinstate Monica - notmaynard
"((String1))" [2 ...- 2] # => "String1"
Monica wieder einsetzen - notmaynard
1
ruby-doc.org/core-1.9.3/String.html
Monica wieder herstellen - notmaynard
Sie fordern eine Schleife an, um viele Zeichenfolgen zu ändern. Wie werden die Zeichenfolgen gespeichert?
Hirolau
Ich weiß, wie man eine Schleife durch alle Saiten macht. Ich wollte nur den Teil zur Manipulation der Saiten. Tut mir leid, dass ich das komisch formuliert habe
Cristiano

Antworten:

164

Gehen Sie wie folgt vor String#tr:

 "((String1))".tr('()', '')
 # => "String1"
Arup Rakshit
quelle
7
Es gibt auch eine destruktive Version tr!, die eine Zeichenfolge an Ort und Stelle modifiziert, wiemy_string.tr!(')(','')
bonh
8
Beachten Sie, dass diese Funktion nicht vom Anfang oder Ende abgeschnitten wird, sondern den gesamten Text in der Zeichenfolge vollständig ersetzt.
Jordanien
3
Irreführend und falsch. Tr ist keine Trimmfunktion, sondern eine Ersatzfunktion. Die beiden sind sehr unterschiedliche Operationen.
Zane Claes
1
@ ZaneClaes Ja. OP verwendete einen falschen Begriff, um zu erklären, was das OP tatsächlich will. Die Antwort hat gezeigt, wie die Ausgabe erreicht werden kann.
Arup Rakshit
39

Wenn Sie nur die ersten beiden Zeichen und die letzten beiden Zeichen entfernen möchten, können Sie negative Indizes für die Zeichenfolge verwenden:

s = "((String1))"
s = s[2...-2]
p s # => "String1"

Wenn Sie alle Klammern aus der Zeichenfolge entfernen möchten, können Sie die Löschmethode für die Zeichenfolgenklasse verwenden:

s = "((String1))"
s.delete! '()'
p s #  => "String1"
jbr
quelle
8
Dadurch werden alle Klammern gelöscht, auch die in der Mitte der Zeichenfolge, was (scheinbar) nicht das ist, was OP will. Wenn dies gewünscht wird, ist dies die eleganteste Lösung.
Stellen Sie Monica wieder her - notmaynard
20

Verwenden String#gsubmit regulären Ausdrücken:

"((String1))".gsub(/^\(+|\)+$/, '')
# => "String1"
"(((((( parentheses )))".gsub(/^\(+|\)+$/, '')
# => " parentheses "

Dadurch werden nur umgebende Klammern entfernt.

"(((((( This (is) string )))".gsub(/^\(+|\)+$/, '')
# => " This (is) string "
falsetru
quelle
2
+1 für das zweite Beispiel (nur umgebende Klammern entfernen).
Bhavneet Singh Bajwa
20

Für diejenigen, die darauf stoßen und nach Leistung suchen, sieht es so aus #deleteund #trist ungefähr gleich schnell und 2-4x schneller als gsub.

text = "Here is a string with / some forwa/rd slashes"
tr = Benchmark.measure { 10000.times { text.tr('/', '') } }
# tr.total => 0.01
delete = Benchmark.measure { 10000.times { text.delete('/') } }
# delete.total => 0.01
gsub = Benchmark.measure { 10000.times { text.gsub('/', '') } }
# gsub.total => 0.02 - 0.04
daino3
quelle
3
Vier Jahre später ... :-) Wenn ich Ihr Benchmarking um ein paar Größenordnungen (1_000_000 Läufe) erhöhe, stelle ich fest, dass mit demselben Code, den Sie oben verwenden, das Löschen etwas schneller als tr ausgeführt wird, wobei das Löschen bei etwa liegt ein Verhältnis von tr von 0,92 und g etwas weniger als das 1,5-fache von delete (tatsächlich ~ 1,46 von delete und ~ 1,39 von tr). ymmv natürlich. Dies ist auf Ruby 2.6.3 auf einem 2018 MBP 13. Vielen Dank für das Benchmarking dieser drei Methoden!
likethesky
1

Hier ist ein noch kürzerer Weg, um dies zu erreichen:

1) mit Negative character class pattern matching

irb(main)> "((String1))"[/[^()]+/]
=> "String1"

^- Entspricht allem, was NICHT in der Charakterklasse enthalten ist. Innerhalb der Charakterklasse haben wir (und)

Oder mit globaler Substitution "AKA: gsub" wie andere erwähnt haben.

irb(main)> "((String1))".gsub(/[)(]/, '')
=> "String1"
zee
quelle
Ihre beiden Antworten haben unterschiedliche Ergebnisse ((a))b. Der erste wird nur zurückkehren a, der zweite wird zurückkehrenab
Ulysse BN