2

I have this code that checks if an email is valid:

$email = "abc123@sdsd.com"; 
$regex = '/^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,3})$/'; 
if (preg_match($regex, $email)) {
 echo $email . " is a valid email. We can accept it.";
} else { 
 echo $email . " is an invalid email. Please try again.";
}

assuming that I have the following string below:

<html>
<body>
<p>abc123@sdsd.com</p>
</body>
</html>

How could I check if that string has an email or not? (since it does not work with the above code)

Lacrifilm
  • 253
  • 5
  • 15

2 Answers2

6

The ^ and $ are anchors, requiring the full string match. If you take that off it will match an email somewhere in the string.

Regex Demo: https://regex101.com/r/xI0bC2/1

PHP Usage (with updated to store found email):

<?php
$email = "<html>
<body>
<p>abc123@sdsd.com</p>
</body>
</html>"; 
$regex = '/[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,3})/'; 
if (preg_match($regex, $email, $email_is)) {
 echo $email_is[0] . " is a valid email. We can accept it.";
} else { 
 echo $email . " is an invalid email. Please try again.";
}

PHP Demo: https://eval.in/618679

chris85
  • 23,846
  • 7
  • 34
  • 51
2

There isn't real solution to this problem, since you will easily obtain false positive.

First thing, your pattern is too naive and doesn't match many email addresses that are correct. However a pattern that matches all email addresses doesn't really exist (or is too complicated and inefficient).

A compromise is to select all text nodes that contains a @ using XPath. Then you split each text node on white-spaces and you test each part with the build-in email validation PHP function: filter_var ($part, FILTER_VALIDATE_EMAIL)

Casimir et Hippolyte
  • 88,009
  • 5
  • 94
  • 125