Як видалити певні символи з рядка в Ruby?


85

У мене є кілька рядків, які виглядають так:

"((String1))"

Всі вони різної довжини. Як я міг видалити дужки з усіх цих рядків у циклі?


2
Видалити дужки або видалити перші два та останні два символи із "випадкового" рядка? ( На насправді випадковим чином ?)
відновило Моніка - notmaynard

"((String1))" [2 ...- 2] # => "String1"
відновити Моніку - notmaynard


Ви просите цикл, щоб змінити багато рядків, як вони зберігаються?
hirolau

Я знаю, як зробити цикл по всіх рядках, я просто хотів, щоб частина маніпуляції рядками, вибачте, я сформулювала це дивно
Кріштіану

Відповіді:


168

Зробіть, як показано нижче, використовуючи String#tr:

 "((String1))".tr('()', '')
 # => "String1"

7
Існує також деструктивна версія, tr!яка змінить рядок на місці, наприкладmy_string.tr!(')(','')
bonh

8
Зверніть увагу, що ця функція полягає не в обрізанні з початку чи в кінці, а в повній заміні всього тексту в рядку.
Йорданія

3
Оманливий і неправильний. Tr - це не функція обрізки, це функція заміни. Це дуже різні операції.
Зейн Клас,

1
@ZaneClaes Так. OP використав неправильний термін, щоб пояснити, чого насправді хоче OP. Відповідь показав, як досягти результату.
Arup Rakshit

42

Якщо ви просто хочете видалити перші два символи та останні два, тоді ви можете використовувати негативні індекси у рядку:

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

Якщо ви хочете видалити всі дужки зі рядка, ви можете скористатися методом delete у класі рядків:

s = "((String1))"
s.delete! '()'
p s #  => "String1"

8
Це видалить усі дужки, навіть ті, що знаходяться в середині рядка, а це (мабуть) не те, що хоче OP. Якщо цього хочеться, то це найелегантніше рішення.
Відновити Моніку - notmaynard

22

Для тих, хто стикається з цим і шукає продуктивності, це виглядає #deleteі #trприблизно однаково за швидкістю і в 2-4 рази швидше, ніж 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

3
Через чотири роки ... :-) Я виявляю, якщо підніму ваш бенчмаркінг на пару порядків (1_000_000 прогонів), що з тим самим кодом, який ви використовуєте вище, я видаляю, що працює трохи швидше, ніж tr, з delete приблизно коефіцієнт 0,92 tr, а gsub трохи менше 1,5x видалення (насправді ~ 1,46 видалення і ~ 1,39 tr). ymmv звичайно. Це на Ruby 2.6.3 на MBP 13 2018 року. Дякуємо за порівняльний аналіз цих трьох методів!
likethesky

21

Використання String#gsubз регулярним виразом:

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

Це видалить лише оточуючі дужки.

"(((((( This (is) string )))".gsub(/^\(+|\)+$/, '')
# => " This (is) string "

2
+1 для другого прикладу (вилучіть лише навколишні дужки).
Bhavneet Singh Bajwa

1

Ось ще коротший спосіб досягнення цього:

1) з використанням Negative character class pattern matching

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

^- Відповідає нічому, що НЕ в класі персонажів. Всередині класу charachter ми маємо (і)

Або із глобальною заміною "AKA: gsub", як згадували інші.

irb(main)> "((String1))".gsub(/[)(]/, '')
=> "String1"

Ваші дві відповіді мають різні результати ((a))b. Перший повернеться лише a, другий повернетьсяab
Улісс БН
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.