Ruby замените строку на захваченный шаблон регулярного выражения

У меня возникли проблемы с переводом на Ruby.

Вот фрагмент JavaScript, который делает именно то, что я хочу сделать:

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

Я пробовал gsub, sub и replace, но никто не делает того, чего я ожидаю.

Вот примеры вещей, которые я пробовал:

"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 }

Ответ 1

Попробуйте '\1' для замены ( одинарные кавычки важны, в противном случае вам нужно избежать \):

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

Но поскольку вы только заинтересованы в группе захвата, обратите внимание, что вы можете индексировать строку с регулярным выражением:

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

Ответ 2

\1 в двойных кавычках необходимо экранировать. Поэтому вы хотите либо

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

или

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

см. документы в gsub, где говорится: "Если это строка с двойными кавычками, обе обратные ссылки должны предшествовать дополнительный обратная косая черта".

При этом, если вы просто хотите получить результат матча, вы можете сделать:

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

или

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

Обратите внимание, что (?=:) - это не захватывающая группа, так что : не отображается в вашем матче.

Ответ 3

 "foobar".gsub(/(o+)/){|s|s+'ball'}
 #=> "fooballbar"

Ответ 4

def get_code(str)
  str.sub(/^(Z_.*): .*/, '\1')
end
get_code('Z_foo: bar!') # => "Z_foo"

Ответ 5

Если вам нужно использовать регулярное выражение для фильтрации некоторых результатов, а THEN использовать только группу захвата, вы можете сделать следующее:

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"