Ruby regex- does gsub store what it matches?

17,431

Solution 1

From the fine manual:

If replacement is a String it will be substituted for the matched text. It may contain back-references to the pattern’s capture groups of the form \d, where d is a group number, or \k<n>, where n is a group name. If it is a double-quoted string, both back-references must be preceded by an additional backslash. However, within replacement the special match variables, such as &$, will not refer to the current match.
[...]
In the block form, the current match string is passed in as a parameter, and variables such as $1, $2, $`, $&, and $' will be set appropriately. The value returned by the block will be substituted for the match on each call.

If you don't care about capture groups (i.e. things like (expr) in the regex) then you can use the block form and $&:

>> 'where is pancakes house?'.gsub(/is/) { "-#{$&}-" }
=> "where -is- pancakes house?"

If you do have capture groups then you can use \n in the replacement string:

>> 'where is pancakes house?'.gsub(/(is)/, '-\1-')
=> "where -is- pancakes house?"

or $n in the block:

>> 'where is pancakes house?'.gsub(/(is)/) { "-#{$1}-" }
=> "where -is- pancakes house?"

Solution 2

I found out here that gsub's matches could actually be accessed through the Regexp.last_match variable (class MatchData) like this:

my_string.gsub(my_regexp){ Regexp.last_match.inspect }

To give a more practical example, if you want to log all matches, it may be used as follows:

"Hello world".gsub(/(\w+)/) { Regexp.last_match.captures.each{ |match| Rails.logger.info "FOUND: #{match}"} }

#Rails log:
FOUND: Hello
FOUND: world

In your specific case, you could do something like this:

mystring.gsub(/(matchthisregex)/){ mystring = "replace_with_#{Regexp.last_match[0].to_s}this"}

Solution 3

For all ruby versions: Simple way to get matched string.

.gsub(/matched_sym/) {|sym| "-#{sym}-"}
Share:
17,431
Tommy
Author by

Tommy

Updated on July 28, 2022

Comments

  • Tommy
    Tommy almost 2 years

    If i use

    .gsub(/matchthisregex/,"replace_with_this")
    

    does gsub store what it matches with the regex somewhere? I'd like to use what it matches in my replacement string. For example something like

    "replace_with_" + matchedregexstring + "this"
    

    in my above example where the matchedregexstring would be the stored match from gsub? Sorry if that was confusing, I don't know how else to word that.

  • matt
    matt about 11 years
    Aha! - so the extra `` that appears in the docs are just artefacts from Rdoc. I’ve been scratching my head trying to figure out what they meant.
  • mu is too short
    mu is too short about 11 years
    @matt: You mean the extra backslashes, right? #*&#$ Markdown, see my $-backtick variable for more fun like that :) Yeah, you need to say \\1 if you use double quotes but \1 is fine if you use single quotes (which I always do unless I need interpolation).
  • matt
    matt about 11 years
    Yes, \ not ``. I hadn’t noticed. I think comments could do with a preview sometimes.