Search code examples
regexerlangelixirelixir-iex

Elixir regex matching literal backslash


Surprisingly the regex matcher does not match backslash correcly. For example

Regex.split(~r{\\}, "C:\foo\bar")
["C:\foo\bar"]
Regex.match?(~r/\\/, "C:\foo\bar")
false

I would expect a positive match, but maybe I'm escaping \ wrong. Let's test that out:

Regex.escape("\\")
"\\\\"
Regex.split(~r{\\\\}, "C:\foo\bar")
["C:\foo\bar"]
Regex.match?(~r/\\\\/, "C:\foo\bar")
false

Still no match. Fairly confused at this point. How do you escape \ in a regex to match a literal \ as you can see in my usecase I would like to split a windows path.


Solution

  • Regex is fine; your input is not what you think it is. Backslash inside strings escapes.

    String.split("C:\foo\bar", "")
    #⇒ ["", "C", ":", "\f", "o", "o", "\b", "a", "r", ""]
    
    String.length("C:\foo\bar")
    #⇒ 8
    

    Note "\f" and "\b" there. The string contains no backslash, but it contains "\f" and "\b" codepoints.

    That said, you need to pass a proper string to Regex.split/3 to yield the expected result.

    Regex.split(~r|\\|, "C:\\foo\\bar")
    #⇒ ["C:", "foo", "bar"]