fast regex match excluding certain words

Viewed 70

I have the following regex pattern to find an email address in my code:

/[\._a-zA-Z0-9-]+@[\._a-zA-Z0-9-]{8,}/i

I want to make sure it does not match a certain string if it includes:

abc
xyz

Just to exclude the abc I have tried:

/(?!.*abc)[\._a-zA-Z0-9-]+@[\._a-zA-Z0-9-]{8,}/i

But that is horribly slow.

2 Answers

You need to "anchor" the regex to a position that can be found by the regex engine in an optimal way. The best way is to "tie" it to a word boundary position, and that should work here since emails start with word chars:

/\b(?!\S*abc)[\w.-]+@[\w.-]{8,}/i

BTW, [_a-zA-Z0-9] is equal to \w in JavaScript regex. Details:

  • \b - a word boundary
  • (?!\S*abc) - a negative lookahead that fails the match if there are zero or more non-whitespace chars and then abc immediately to the right of the current location
  • [\w.-]+ - one or more word, . or - chars
  • @ - a @ char
  • [\w.-]{8,}- eight or more word, . or - chars.

You can do it in two steps. Use a regular expression to find the email address, then check that it doesn't contain any of the prohibited strings.

if (preg_match('/[\._a-zA-Z0-9-]+@[\._a-zA-Z0-9-]{8,}/i', $text, $match) && !preg_match('/abc|xyz/i', $match[0])) {
    $email = $match[0];
}
Related