Ruby 字符串 gsub 捕获无效如果使用它们

Ruby string gsub captures invalidated if using them

这里有一段典型的 gsub 代码:

str = '[caption id="attachment_3655" align="aligncenter" width="1024"]<a href="http://test.com/wp-content/uploads/2018/01/sample-image.jpg"><img class="size-large wp-image-3655" src="{{ site.baseurl }}/assets/sample-image-1024x768.jpg" alt="" width="1024" height="768" /></a> Image title[/caption]'

p str.gsub(/\[caption.*?\]<a href=\"(.+?)\".*?><img .*?\/><\/a>(.+?)\[\/caption\]/) { |match|
  href = .sub("http://test.com/wp-content/uploads/", "")
  title = 

  "#{href} - #{title}"
}

此调用后 .sub("http://test.com/wp-content/uploads/", "") 捕获数据 </code> 变为 <code>nil。如果我首先访问上面的 </code> 它就可以了。为什么调用 <code>sub() 会使捕获无效?

Why calling sub() invalidates captures?

出于与调用 gsub 设置 相同的原因。这是这些方法中的一个 side-effect,他们设置了这些 pseudo-global 个变量。

阅读文档后,您可能会觉得这些变量仅以块形式设置。事实并非如此。

'foobar'.sub(/(foo)/, 'bar') # => "barbar"
 # => "foo"

并且由于您的 sub 模式不包含匹配组(它甚至不是正则表达式),捕获 pseudo-global 自然会被清除。

'foobar'.sub('foo', 'bar') # => "barbar"
 # => nil