Dan Fitzpatrick wrote:
> I am converting URLs in a text file to hyperlinks with the following
> regex. But the results only show up after the gsub is run a second time.
>
> str = "A link to http://ruby-lang.org"
> str.gsub(/([\s|\>|\[|\(])((ftp:\/\/|http(s?):\/\/))([\w\.\?\/&=\-~:%]+)\b/i,
> "#{$1}<a href='#{$3}#{$5}#{$6}' target='_blank'>#{$5}#{$6}</a>")
> #=> "A link to<a href='' target='_blank'></a>"
> str.gsub(/([\s|\>|\[|\(])((ftp:\/\/|http(s?):\/\/))([\w\.\?\/&=\-~:%]+)\b/i,
> "#{$1}<a href='#{$3}#{$5}#{$6}' target='_blank'>#{$5}#{$6}</a>")
> #=> "A link to <a href='http://ruby-lang.org'
> target='_blank'>ruby-lang.org</a>"
>
> Is there another way to do this?
>

Hi,

Just a small change.

You need to use the block form of gsub, here, because the $n backrefs
are not set until the regex has completed.  When using the non-block
form, you can normally use \1, \2 etc. instead of $1, $2 etc. but,
because you're using interpolation with #{...} inside your replacement
string, it gets a bit tricky doubling up the backslashes.

That's really not clear at all, sorry :-)

The reason why your example took two runs, is because the first run
sets the $n backrefs exactly the way you want them for the second run.

#--------------------------------------
str = "A link to http://ruby-lang.org"

res = str.gsub(/([\s|\>|\[|\(])((ftp:\/\/|http(s?):\/\/))([\w\.\?\/&=\-~:%]+)\b/i) do
    "#{$1}<a href='#{$3}#{$5}#{$6}' target='_blank'>#{$5}#{$6}</a>"
end

puts res  #-> A link to <a href='http://ruby-lang.org' target='_blank'>ruby-lang.org</a>
#--------------------------------------


daz