Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ruby, gsub and regex

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.

like image 526
Jim Neath Avatar asked Aug 17 '09 12:08

Jim Neath


People also ask

Does GSUB use regex?

Regular expressions (shortened to regex) are used to operate on patterns found in strings. They can find, replace, or remove certain parts of strings depending on what you tell them to do. In Ruby, they are always contained within two forward slashes.

What does GSUB do in Ruby?

gsub! is a String class method in Ruby which is used to return a copy of the given string with all occurrences of pattern substituted for the second argument. If no substitutions were performed, then it will return nil. If no block and no replacement is given, an enumerator is returned instead.

What does GSUB return?

gsub (s, pattern, repl [, n]) Returns a copy of s in which all (or the first n , if given) occurrences of the pattern have been replaced by a replacement string specified by repl , which can be a string, a table, or a function. gsub also returns, as its second value, the total number of matches that occurred.

How do I remove special characters from a string in Ruby?

In Ruby, we can permanently delete characters from a string by using the string. delete method. It returns a new string with the specified characters removed.


1 Answers

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

like image 52
sepp2k Avatar answered Sep 21 '22 18:09

sepp2k