Ruby用捕获的正则表达式模式替换字符串


121

我在将其转换为Ruby时遇到麻烦。

这是一段JavaScript,完全可以满足我的需求:

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

我尝试了gsubsubreplace,但是似乎都没有达到我的期望。

以下是我尝试过的事情的示例:

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

您应该显示您尝试过的实际代码。
2012年

@琥珀我放了我尝试过的样品。
JD Isaacks 2012年

Answers:


192

尝试'\1'替换(单引号很重要,否则您需要转义\):

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

但是,由于您似乎只对捕获组感兴趣,因此请注意,可以使用正则表达式为字符串建立索引:

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

68
请注意,这仅在替换字符串在单引号内时才有效。我浪费了5分钟才弄明白了。
Vicky Chijwani,

7
@MarkThomas-通常我们在没有阅读完整答案的情况下首先尝试最常见/可接受的答案。通常,这似乎是解决问题的最有效方法。薇琪休息一下!:)
Josh M.

@VickyChijwani很好的注释,但也请注意,在使用Ruby inline时(在上使用命令行-e),更可能会看到双引号printf "Punkinhead the name" | ruby -ne 'puts gsub /.*(the name)/, "Jonathans \\1"'因为提供给的表达式-e通常用单引号引起来。
乔纳森·科玛

如何对字符串中所有出现的模式执行此操作?
Jagdeep Singh

1
@JagdeepSingh,默认情况下,它将替换所有出现的事件。
Iulian Onofrei

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"

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

0

$ 变量仅设置为匹配到块中:

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

这也是在比赛中调用方法的唯一方法。这不会更改匹配,只会更改strip“ \ 1”(保持不变):

"Z_sdsd: sdsd".gsub(/^(Z_.*): .*/, "\\1".strip)
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.