PHP Email extractor with spaces

Viewed 54

I have a function to extract emails from string

$extractor = function ($str) {
        $str = str_replace('[at]', '@', $str);
        $str = str_replace('(dot)', '.', $str);

        $regexp = '/([a-z0-9_\.\-])+\@(([a-z0-9\-])+\.)+([a-z0-9]{2,4})+/i';
        preg_match_all($regexp, $str, $m);

        return isset($m[0]) ? $m[0] : [];
    };

    $test_string = 'This is a test string...

        test1@example.org

        Test different formats:
        test2@example.org;
        <a href="test3@example.org">foobar</a>
        <test4@example.org>

        strange formats:
        test5@example.org
        test6[at]example.org
        test7@example.net.org.com
        test8@ example.org
        test9@!foo!.org
        test10.abc [at] hello (dot) com

        foobar
';

    dd($extractor($test_string));

These email cannot be extracted because the spaces before/after @ and [at].

test8@ example.org
test10.abc [at] hello (dot) com

How can I ignore those spaces in my regex. Thank you.

1 Answers

I suggest pre-processing the input a bit more, by removing any whitespaces around [at], (dot) and @, that is, replace

$str = str_replace('[at]', '@', $str);
$str = str_replace('(dot)', '.', $str);

with

$str = preg_replace('/\s*(?:\[at]|@)\s*/', '@', $str); // replace [at] or @ with any amount of spaces before and after with @
$str = preg_replace('/\s*\(dot\)\s*/', '.', $str); // replace (dot) with any amount of spaces before and after with .

See the PHP demo:

$extractor = function ($str) {
    $str = preg_replace('/\s*(?:\[at]|@)\s*/', '@', $str);
    $str = preg_replace('/\s*\(dot\)\s*/', '.', $str);
    $regexp = '/\b[a-z0-9_.-]+@(?:[a-z0-9-]+\.)+[a-z0-9]{2,4}\b/i';
    preg_match_all($regexp, $str, $m);
    return isset($m[0]) ? $m[0] : [];
};

Output:

Array
(
    [0] => test1@example.org
    [1] => test2@example.org
    [2] => test3@example.org
    [3] => test4@example.org
    [4] => test5@example.org
    [5] => test6@example.org
    [6] => test7@example.net.org.com
    [7] => test8@example.org
    [8] => test10.abc@hello.com
)
Related