【问题标题】:Ruby, gsub and regexRuby、gsub 和正则表达式
【发布时间】:2009-08-17 12:17:27
【问题描述】:

快速背景:我有一个包含对其他页面的引用的字符串。这些页面使用以下格式链接到:“#12”。后跟页面 ID 的哈希值。

假设我有以下字符串:

str = 'This string links to the pages #12 and #125'

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

page_ids = str.scan(/#(\d*)/).flatten
=> [12, 125]

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

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

这适用于#12,但它会将#125 的“12”部分链接到 ID 为 12 的页面。

任何帮助都会很棒。

【问题讨论】:

    标签: ruby-on-rails ruby regex gsub


    【解决方案1】:

    您无需先提取 id 再替换它们,而是一次找到并替换它们:

    str = str.gsub(/#(\d*)/) { link_to("##{$1}", page_path($1)) }
    

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

    PS:如果str 没有在其他任何地方引用,您可以使用str.gsub! 代替str = str.gsub

    【讨论】:

    • 这是有效的,但是,根据文本的内容,可能会产生误报。想象一下,他有 125 个页面可供参考,并且页面文本中有 #112325 之类的字符串(订单号等),这将在每个误报的情况下产生指向死页的链接。虽然使用页面列表和单词边界进行搜索并非万无一失,但它比此解决方案更强大,尽管它很优雅。
    • 如果有像#112325 这样的字符串,它会在page_ids 数组中,所以无论哪种方式都会产生死链接。请注意,我的 gsub 使用与 OP 的扫描相同的正则表达式。所以他们会找到完全相同的 id。
    • 您的正则表达式将找到英镑符号后面的任何数字序列。从数组中输入它们将确保磅符号后面的数字序列是想要的数字序列。 JimNeath 唯一需要的是与他已经建立的页面索引相对应的那些。 #112325 或 #100000000000000 不太可能出现在该页面索引中,但它们将被 /#(\d*)/ 捕获。
    • 你在说什么?我的正则表达式与 Jim 的扫描正则表达式相同。 /#(\d*)/ 捕获的任何内容都将在 page_ids 正则表达式中,因为这是用于填充它的正则表达式。
    • 哎呀,我“扫描”了这部分问题。您是对的,只要列表以这种方式组装并且随后没有被过滤,该正则表达式就可以工作。如果他足够幸运,没有匹配的子序列只代表他想要索引的页面,那么 /#(\d*)/ 将会很好地工作。顺便说一句,我不知道你可以像这样将一个块传递给 gsub。非常好,谢谢你的提示。
    【解决方案2】:

    如果您的索引总是以单词边界结尾,您可以匹配:

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

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

    【讨论】:

    • 太棒了。我不知道\ b。先生,您是救生员。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多