Ruby,gsub和regex

Jim*_*ath 9 ruby regex ruby-on-rails gsub

快速背景:我有一个字符串,其中包含对其他页面的引用.页面链接使用格式:"#12".哈希后跟页面的ID.

说我有以下字符串:

str = 'This string links to the pages #12 and #125'
Run Code Online (Sandbox Code Playgroud)

我已经知道需要链接的页面的ID:

page_ids = str.scan(/#(\d*)/).flatten
=> [12, 125]
Run Code Online (Sandbox Code Playgroud)

如何遍历页面ID并将#12和#125链接到各自的页面?我遇到的问题是如果我执行以下操作(在rails中):

page_ids.each do |id|
  str = str.gsub(/##{id}/, link_to("##{id}", page_path(id))
end
Run Code Online (Sandbox Code Playgroud)

这适用于#12,但它将#125的"12"部分链接到ID为12的页面.

任何帮助都是极好的.

sep*_*p2k 22

您可以直接查找并替换它们,而不是首先提取ID然后替换它们:

str = str.gsub(/#(\d*)/) { link_to("##{$1}", page_path($1)) }
Run Code Online (Sandbox Code Playgroud)

即使你不能省略提取步骤,因为你在其他地方也需要id,这应该快得多,因为它不必遍历每个id的整个字符串.

PS:如果str没有从其他任何地方引用,你可以使用str.gsub!而不是str = str.gsub

  • 如果有一个像#112325这样的字符串,它将在page_ids数组中,所以它会产生一个死链接.请注意,我的gsub使用与OP扫描相同的正则表达式.所以他们会找到完全相同的ID. (2认同)
  • 你在说什么?我的正则表达式与Jim的扫描正则表达式相同.由`/#(\ d*)/`捕获的任何内容都将在page_ids正则表达式中,因为这是用于填充它的正则表达式. (2认同)

Pin*_*hle 13

如果索引始终以字边界结束,则可以匹配:

page_ids.each do |id|
  str = str.gsub(/##{id}\b/, link_to("##{id}", page_path(id))
end
Run Code Online (Sandbox Code Playgroud)

您只需要\b在搜索模式上添加单词边界符号,就不需要替换模式.