Quick question about Warning 14

Hello,

I’m having a small issue with a warning 14 : illegal backslash escape in string.
I need to remove all $ from a name. I’m therefore using
Str.global_replace (Str.regexp "\$") "_" name
This raises Warning 14: illegal backslash escape in string. because I’m escaping a $ which usually doesn’t have to be escaped, except in a regexp…

How can I prevent the warning ? Should I just disable the warning completely ?

If you write it like that you’re escaping the $, which is illegal in OCaml like the warning tells you. To insert the character \ in a string you have to escape it, as in "\\$". But since you’re also compiling the string to a regexp you actually have to escape it twice: once for OCaml’s lexer and the second time for Str’s. So the correct way to escape $ in a regular expression is "\\\\$". (See below)

I understand the theory, however, in utop :

Str.global_replace (Str.regexp "\\\\$") "_" "aaaaaaa$aaaaaaaaa$";;
- : string = "aaaaaaa$aaaaaaaaa$"

It doesn’t seem to work…

While

Str.global_replace (Str.regexp "\$") "_" "aaaaaaa$aaaaaaaaa$";;
Characters 32-34:
Warning 14: illegal backslash escape in string.
- : string = "aaaaaaa_aaaaaaaaa_"

Raises the warning but works

Weird… Have you tried with just two \?

1 Like

Ah, I hadn’t, and it works.
Though I don’t really understand why, I’d expect it to match a \ at the end of the string

Thank you !!!

The regexp you want to write is \$ if you want to write this regexp as an OCaml literal string you have to write "\\$" because backslash needs to be escaped in OCaml strings.

1 Like

Yeah, actually it makes sense :slight_smile: Thanks !

Yeah I got confused for a moment there, two levels of quotations are a bit too much…

"\\\\$" compiles to /\\$/ and will match a \ at the end of a string, while "\\$" compiles to /\$/ and will match a $ character. You can actually avoid this by using a quoted string literal:

utop # Str.global_replace (Str.regexp {|\$|}) "_" "aaaaaaa$aaaaaaaaa$";;
- : string = "aaaaaaa_aaaaaaaaa_"
4 Likes

This is indeed a more elegant solution