Ruby замінити рядок захопленим малюнком регулярних виразів


121

У мене виникають проблеми з перекладом цього на Рубі.

Ось фрагмент JavaScript, який робить саме те, що я хочу зробити:

function get_code(str){
    return str.replace(/^(Z_.*): .*/,"$1")​​​​​​​​​​​​​​​​​​​​​​​​​​​;
}

Я спробував gsub , sub та заміну, але, здається, ніхто не робив того, чого я очікував.

Ось приклади речей, які я спробував:

"Z_sdsd: sdsd".gsub(/^(Z_.*): .*/) { |capture| capture }
"Z_sdsd: sdsd".gsub(/^(Z_.*): .*/, "$1")
"Z_sdsd: sdsd".gsub(/^(Z_.*): .*/, "#{$1}")
"Z_sdsd: sdsd".gsub(/^(Z_.*): .*/, "\1")
"Z_sdsd: sdsd".gsub(/(.).*/) { |capture| capture }

Ви повинні показати фактичний код того, що ви спробували.
Бурштин

@Amber Я поставив зразок, який я пробував.
JD Isaacks

Відповіді:


192

Спробуйте '\1'замінити ( важливі окремі лапки , інакше вам потрібно уникнути \):

"foo".gsub(/(o+)/, '\1\1\1')
#=> "foooooo"

Але оскільки вам здається, що вас цікавить лише група захоплення, зауважте, що ви можете індексувати рядок за допомогою регулярного вираження:

"foo"[/oo/]
#=> "oo"
"Z_123: foobar"[/^Z_.*(?=:)/]
#=> "Z_123"

68
Зауважте, що це працює лише в тому випадку, якщо рядок заміни знаходиться в одному лапці . Я витратив 5 хвилин, з'ясувавши це.
Vicky Chijwani

7
@MarkThomas - часто ми спершу спробуємо відповісти верхню / прийняту відповідь, не читаючи всі відповіді. Це, як правило, є найбільш ефективним засобом вирішення проблеми. Дайте Вікі відпочити! :)
Джош М.

@VickyChijwani Хороший коментар, але також зауважте, що при використанні Ruby inline (у командному рядку з -e) більше шансів побачити подвійні лапки : printf "Punkinhead the name" | ruby -ne 'puts gsub /.*(the name)/, "Jonathans \\1"'оскільки надане вираження -eзазвичай загорнуте в одинарні лапки.
Джонатан Комар

Як це зробити для всіх випадків появи шаблону в рядку?
Jagdeep Singh

1
@JagdeepSingh, за замовчуванням він замінює всі події.
Юліан Онофрей

36

\1у подвійних лапках потрібно уникати. Тож ви хочете і те, і інше

"Z_sdsd: sdsd".gsub(/^(Z_.*): .*/, "\\1")

або

"Z_sdsd: sdsd".gsub(/^(Z_.*): .*/, '\1')

перегляньте документи на gsub, де написано: "Якщо це рядок з подвійним цитуванням, обом зворотним посиланням повинно передувати додатковий зворотний ривок".

Це було сказано, якщо ви просто хочете результат матчу, ви можете зробити:

"Z_sdsd: sdsd".scan(/^Z_.*(?=:)/)

або

"Z_sdsd: sdsd"[/^Z_.*(?=:)/]

Зауважте, що (?=:)група не охоплює, так що :вона не відображається у вашій відповідності.



5

Якщо вам потрібно використовувати регулярний вираз для фільтрації деяких результатів, а потім використовувати тільки групу захоплення, ви можете зробити наступне:

str = "Leesburg, Virginia  20176"
state_regex = Regexp.new(/,\s*([A-Za-z]{2,})\s*\d{5,}/)
# looks for the comma, possible whitespace, captures alpha,
# looks for possible whitespace, looks for zip

> str[state_regex]
=> ", Virginia  20176"

> str[state_regex, 1] # use the capture group
=> "Virginia"


0

$ змінні встановлюються лише у відповідність до блоку:

"Z_sdsd: sdsd".gsub(/^(Z_.*): .*/) { "#{ $1.strip }" }

Це також єдиний спосіб викликати метод на відповідність. Це не змінить відповідність, лише strip"\ 1" (залишивши її незмінною):

"Z_sdsd: sdsd".gsub(/^(Z_.*): .*/, "\\1".strip)
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.