1

I am generating some RTF strings and need the \'bd code. I am having problem with the sub and gsub commands.

puts 'abc'.sub('a',"\\'B")  => "bcBbc"

The statement replaces the target with 'B' without the \', and copies the remainder of the string to the front. I've tried a lot of variations and it seems that the problem is the \' itself.

I have ways of getting around this, but I'd like to know whether I'm doing something fundamentally wrong or whether this is a quirk with Ruby.

Thanks

Mike Blyth
  • 4,158
  • 4
  • 30
  • 41

1 Answers1

2

From the Ruby documentation:

Similarly, \&, \', \`, and \+ correspond to special variables, $&, $', $`, and $+, respectively.

And here, the documentation goes on to say:

  • $~ is equivalent to ::last_match;
  • $& contains the complete matched text;
  • $` contains string before match;
  • $' contains string after match;
  • $1, $2 and so on contain text matching first, second, etc capture group;
  • $+ contains last capture group.

Example:

m = /s(\w{2}).*(c)/.match('haystack') #=> #<MatchData "stac" 1:"ta" 2:"c">
$~                                    #=> #<MatchData "stac" 1:"ta" 2:"c">
Regexp.last_match                     #=> #<MatchData "stac" 1:"ta" 2:"c">

$&      #=> "stac"
        # same as m[0]
$`      #=> "hay"
        # same as m.pre_match
$'      #=> "k"
        # same as m.post_match
$1      #=> "ta"
        # same as m[1]
$2      #=> "c"
        # same as m[2]
$3      #=> nil
        # no third group in pattern
$+      #=> "c"
        # same as m[-1]

So, \' in a substitution replacement string has a special meaning. It means "The portion of the original string after the match" - which, in this case, is "bc".

So rather than getting \'Bbc, you get bcBbc

Therefore unfortunately, in this odd scenario, you'd need to double-escape the backslashes:

puts 'abc'.sub('a',"\\\\'B")  => "\'Bbc"
3limin4t0r
  • 19,353
  • 2
  • 31
  • 52
Tom Lord
  • 27,404
  • 4
  • 50
  • 77