Ruby, gsub and regex

20,167

Solution 1

if your indexes always end at word boundaries, you can match that:

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

you only need to add the word boundary symbol \b on the search pattern, it is not necessary for the replacement pattern.

Solution 2

Instead of extracting the ids first and then replacing them, you can simply find and replace them in one go:

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

Even if you can't leave out the extraction step because you need the ids somewhere else as well, this should be much faster, since it doesn't have to go through the entire string for each id.

PS: If str isn't referred to from anywhere else, you can use str.gsub! instead of str = str.gsub

Share:
20,167
Jim Neath
Author by

Jim Neath

Ruby geek.

Updated on July 17, 2022

Comments

  • Jim Neath
    Jim Neath almost 2 years

    Quick background: I have a string which contains references to other pages. The pages are linked to using the format: "#12". A hash followed by the ID of the page.

    Say I have the following string:

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

    I already know the IDs of the pages that need linking:

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

    How can I loop through the page ids and link the #12 and #125 to their respective pages? The problem I've run into is if I do the following (in rails):

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

    This works fine for #12 but it links the "12" part of #125 to the page with ID of 12.

    Any help would be awesome.