How to use W3C Email Regex in Elixir

Viewed 797

I'm trying to use the following W3C Email Regex in Elixir (source: RegexPal):

/^[a-zA-Z0-9.!#$%&’*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/

In a function that looks like this

def get_type(value) do
    cond do
        String.match?(value, ~r/^[a-zA-Z0-9.!#$%&’*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/) ->
            :email

        String.match?(value, ~r/^\+[1-9][0-9]\d{1,14}$/) ->
            :phone_number
    end
end

But I'm getting a compilation error

unexpected token: "`" (column 56, code point U+0060)

What am I doing wrong here?

3 Answers

This is not particularly answering your question regarding regex, which was perfectly answered by @julp.

I am here to tell do not use regex to validate emails. The regular expression you’ve mentioned is not nearly correct by any means.

Here is an example of a perfectly valid email that won’t pass your regex: "John Smith"@example.com.

More.

So my guess would be: check if there is @ or not.

def get_type(value) do
  if String.contains?(value, "@"),
      do: :email,
    else: :phone_number
end

Sine you used / to delimit the content of your sigil, you need to escape the / character in your regexp. An other solution is to choose a delimiter that is not part of the regexp (like ' or < for example) to avoid the need of escaping.

~R/^[a-zA-Z0-9.!#$%&’*+\/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/
# or
~R<^[a-zA-Z0-9.!#$%&’*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$>

One very practical way of avoiding this problem is to simply write the regex as a string and call Regex.compile! on it.

Regex.compile!("^[a-zA-Z0-9.!#$%&’*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$")
Related