aris
August 31, 2012, 5:50pm
1
Using 1.9.3p194:
puts “+”
puts “\+”
+
puts “\”
\
However not what I’d expect (1):
puts “hi + bye”.gsub(/+/, “\+”)
hi bye
This gives the expected output:
puts “hi + bye”.gsub(/+/, “\\+”)
hi + bye
I can understand why I need to double escape the + to get + in the
output but shouldn’t (1) above at least print “hi + bye”?
[EDIT: Improved title]
kule
August 31, 2012, 9:45pm
2
Because an escape, e.g. \x in a replacement string is the syntax for a
backreference. After ruby evaluates your string to produce +, ruby
hands + to the
regex engine, and the regex engine sees + in a replacement string,
which is the syntax for referring to a matching
subgroup (backreference). In your case, + is especially tricky because
it is a backreference to the global variable $+, which is the last match
from a successful regex match, which in your case is nil. Observe:
puts “hi + bye”.gsub(/(.) +/, " plus \1")
–output:–
h plus i bye
puts $+
–output:–
i
puts “hi + bye”.gsub(/(.) +/, " plus \+")
–output:–
h plus i bye
kule
August 31, 2012, 10:07pm
3
the global variable $+, which is the last match
from a successful regex match, which in your case is nil.
That should read:
…the global variable $+, which is the last match
from a previous successful regex match, which in your case is nil.
kule
August 31, 2012, 10:39pm
4
7stud – wrote in post #1074118:
the regex engine sees + in a replacement string,
which is the syntax for referring to a matching
subgroup (backreference).
Many thanks 7stud - I thought there would have to be a reason behind it
kule
September 1, 2012, 2:01pm
5
I don’t see immediate answers to this in the ML but others might still
have answered it already.
On Fri, Aug 31, 2012 at 5:50 PM, Luke P. [email protected]
wrote:
I can understand why I need to double escape the + to get + in the
output but shouldn’t (1) above at least print “hi + bye”?
There are two levels of escapes and it happens that the backslash is
the escape character for both levels :
string (i.e. what makes “\n” create a string with the line
terminator)
regular expression replacement pattern (e.g. \1 as a backreference)
If you want to have a literal backslash in the result, you need to
escape it, i.e. you need this in the replacement string
\
To get that, you need to escape each backslash so string escaping does
not eat it, so you do
“\\”
irb(main):005:0> puts “\”
=> nil
irb(main):006:0> puts “\\”
\
=> nil
Kind regards
robert