0

I am trying to escape certain characters in a string. In particular, I want to turn

abc/def.ghi into abc\/def\.ghi

I tried to use the following syntax:

1.9.3p125 :076 > "abc/def.ghi".gsub(/([\/.])/, '\\\1')
 => "abc\\1def\\1ghi" 

Hmm. This behaves as if capture replacements didn't work. Yet, when I tried this:

1.9.3p125 :075 > "abc/def.ghi".gsub(/([\/.])/, '\1')
 => "abc/def.ghi"

... I got the replacement to work, but, of course, my prefixes weren't part of it.

What is the correct syntax to do something like this?

1
  • Cf. nitro2k01's answer to my question. Commented Apr 4, 2013 at 16:57

3 Answers 3

1

This should be easier

gsub(/(?=[.\/])/, "\\")
Sign up to request clarification or add additional context in comments.

2 Comments

the slash inside the sq brackets should be escaped but otherwise it does the job. Thanks! I'm still puzzled why my example didn't work though.
The only reason the slash has to be escaped is because / is used as the pattern delimiter, otherwise Ruby would parse it wrong and prematurely terminate the pattern, causing a syntax error. Using gsub(%r{(?=[./])}, "\\") should be fine.
1

If you are trying to prepare a string to be used as a regex pattern, use the right tool:

Regexp.escape('abc/def.ghi')
=> "abc/def\\.ghi"

You can then use the resulting string to create a regex:

/#{ Regexp.escape('abc/def.ghi') }/
=> /abc\/def\.ghi/

or:

Regexp.new(Regexp.escape('abc/def.ghi'))
=> /abc\/def\.ghi/

From the docs:

Escapes any characters that would have special meaning in a regular expression. Returns a new escaped string, or self if no characters are escaped. For any string, Regexp.new(Regexp.escape(str))=~str will be true.

Regexp.escape('\*?{}.')   #=> \\\*\?\{\}\.

2 Comments

I am not sure it works all the time. Try this: Regexp.escape("/")
Why is that wrong? "/" doesn't have to be escaped UNLESS you are using the same value as your pattern delimiter, and that doesn't apply if you interpolate the escaped string into a regex, as per my example, or use a different delimiter like %r{/}.
0

You can pass a block to gsub:

>> "abc/def.ghi".gsub(/([\/.])/) {|m| "\\#{m}"}
=> "abc\\/def\\.ghi"

Not nearly as elegant as @sawa's answer, but it was the only way I could find to get it to work if you need the replacing string to contain the captured group/backreference (rather than inserting the replacement before the look-ahead).

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.