From: daz Date: 2005-07-14T04:15:51+09:00 Subject: Re: Regex back reference in gsub 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}#{$5}#{$6}") > #=> "A link to" > str.gsub(/([\s|\>|\[|\(])((ftp:\/\/|http(s?):\/\/))([\w\.\?\/&=\-~:%]+)\b/i, > "#{$1}#{$5}#{$6}") > #=> "A link to target='_blank'>ruby-lang.org" > > 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}#{$5}#{$6}" end puts res #-> A link to ruby-lang.org #-------------------------------------- daz