Як видалити певні символи з рядка в 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.