String.match? vs =~ Regex.compile!/1

I can’t figure out why there is such a difference between these 2 use cases of Regex match:

Interactive Elixir (1.13.4) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> str = "^\d{1,2}$"
"^\d{1,2}$"
iex(2)> regex = Regex.compile!(str)
~r/^\x7F{1,2}$/
iex(3)> "01" =~ regex
false
iex(4)> String.match?("01", ~r/^\d{1,2}$/)
true

Why it does not match when using Regex.compile!/1 and =~, but it does match when using String.match?/2?

Thank you.

You need to escape the \, otherwise \d is a Unicode DELETE character. If you do:

str = "^\\d{1,2}$"
regex = Regex.compile!(str)
#=> ~r/^\d{1,2}$/

You now get what you expect.

5 Likes

Ah, good to know, thank you. I was also surprised that the following matched as expected:

iex(1)> "01" =~ ~r/^\d{1,2}$/
true
1 Like

~r is a sigil.

There is also ~S for unescaped strings.

"^\d{1,2}$" is equivalent to using the ~s sigil.

iex(1)> "01" =~ ~r/^\d{1,2}$/
true
iex(2)> "01" =~ Regex.compile!(~S/^\d{1,2}$/)
true
iex(3)> "01" =~ Regex.compile!(~s/^\d{1,2}$/)
false
2 Likes