124

I have the following Regular Expression which matches an email address format:

^[\w\.\-]+@([\w\-]+\.)+[a-zA-Z]+$

This is used for validation with a form using JavaScript. However, this is an optional field. Therefore how can I change this regex to match an email address format, or an empty string?

From my limited regex knowledge, I think \b matches an empty string, and | means "Or", so I tried to do the following, but it didn't work:

^[\w\.\-]+@([\w\-]+\.)+[a-zA-Z]+$|\b
Teun Zengerink
  • 4,277
  • 5
  • 30
  • 32
Curtis
  • 101,612
  • 66
  • 270
  • 352
  • 6
    If you *must* validate an email, be as permissive as possible. You'd be surprised how easy it is to miss real, valid and functional email addresses with home-baked regexes. Your regex, for instance, will fail on these valid addresses: joe_blow@foo.com, micro$oft@apple.com, root@localhost, siegfried+roy@lasvegas.com. – Zano Jul 26 '10 at 09:23
  • 1
    Agreeing with Zano, just take a look at this regex http://www.ex-parrot.com/pdw/Mail-RFC822-Address.html – Anders Jul 26 '10 at 09:36
  • @Anders wow, thats a very complex regex! I think I've misunderestimated the complexity of regex – Curtis Jul 26 '10 at 09:50
  • 5
    No, I think you've misunderestimated the complexity of email validation :-) – Zano Jul 26 '10 at 09:55

5 Answers5

281

To match pattern or an empty string, use

^$|pattern

Explanation

  • ^ and $ are the beginning and end of the string anchors respectively.
  • | is used to denote alternates, e.g. this|that.

References


On \b

\b in most flavor is a "word boundary" anchor. It is a zero-width match, i.e. an empty string, but it only matches those strings at very specific places, namely at the boundaries of a word.

That is, \b is located:

  • Between consecutive \w and \W (either order):
    • i.e. between a word character and a non-word character
  • Between ^ and \w
    • i.e. at the beginning of the string if it starts with \w
  • Between \w and $
    • i.e. at the end of the string if it ends with \w

References


On using regex to match e-mail addresses

This is not trivial depending on specification.

Related questions

Community
  • 1
  • 1
polygenelubricants
  • 376,812
  • 128
  • 561
  • 623
15

An alternative would be to place your regexp in non-capturing parentheses. Then make that expression optional using the ? qualifier, which will look for 0 (i.e. empty string) or 1 instances of the non-captured group.

For example:

/(?: some regexp )?/

In your case the regular expression would look something like this:

/^(?:[\w\.\-]+@([\w\-]+\.)+[a-zA-Z]+)?$/

No | "or" operator necessary!

Here is the Mozilla documentation for JavaScript Regular Expression syntax.

Jgonzalez731
  • 343
  • 1
  • 3
  • 7
11

I'm not sure why you'd want to validate an optional email address, but I'd suggest you use

^$|^[^@\s]+@[^@\s]+$

meaning

^$        empty string
|         or
^         beginning of string
[^@\s]+   any character but @ or whitespace
@         
[^@\s]+
$         end of string

You won't stop fake emails anyway, and this way you won't stop valid addresses.

MrWhite
  • 43,179
  • 8
  • 60
  • 84
Zano
  • 2,595
  • 27
  • 33
  • If an address isn't entered into the field, a NULL value is entered into the database, therefore this can be dealt with when it comes to sending out newsletters etc. I appreciate this won't stop fake addresses, and I don't think thats possible at all with Regex, but it'll at least minimise human-error – Curtis Jul 26 '10 at 09:46
  • 1
    I also have customers request this frequently as well. It is really just to keep customers from doing something stupid like entering their phone number in the email field. – Kelly Robins Mar 08 '12 at 17:22
  • 1
    Just wanted to check for an empty String. ^$ worked – Subhashi Dec 18 '19 at 03:08
1

\b matches a word boundary. I think you can use ^$ for empty string.

pritaeas
  • 2,073
  • 5
  • 34
  • 51
0

^$ did not work for me if there were multiple patterns in regex.

Another solution:

/(pattern1)(pattern2)?/g

"pattern2" is optional. If empty, not matched.

? matches (pattern2) between zero and one times.

Tested here ("m" is there for multi-line example purposes): https://regex101.com/r/mezfvx/1

Nubian
  • 153
  • 6