Regular Expression in PHP to filter @name or @name.lastname

Viewed 151

I have a regular expression like preg_match_all (PHP) that filters emails in text.

Example:

txt = " tenho ujm texto onde tem um e-mail georgios@teste.com e seu amigos <a> georgios@lask.com </a> 
        mirian@bagato.com sem contar";

return: georgios@teste.com, georgios@lask.com, mirian@bagato.com

I need to filter from a text, all @firstname.name or @name.

Example:

txt = "Testando se essa pescaria é valida @ju1lio.leao, se não for aciona @alycianne.
Importante deixar @mirian ciente. E a @simone.akemi de sobreaviso.";

return: @mirian,@ju1lio.leao,@alycianne,@simone.akemi

I'm currently using the patterns:

pattern = '/\@([a-z0-9\-])+/i'; 
pattern1 = '/\@(([a-z0-9\-])+\.)+([a-z0-9])+/i';

Return: Array
(
    [0] => @alycianne
    [1] => @ju1lio
    [2] => @ju1lio.leao
    [3] => @mirian
    [4] => @simone
    [5] => @simone.akemi
)

The expressions are filtering names from text incorrectly. Some help/idea ?

2 Answers

Using \@[a-z0-9\-\.]+ for the first pattern will also match the dot in @alycianne. which looks like the end of the string.

In the second pattern that you tried \@(([a-z0-9\-])+\.)+([a-z0-9])+ you are repeating the first group 1 or more times. That group ends on a dot, so to get a match, there should be at least a dot.

The second part of the group is also repeated 1 or more times, so there should also be at least a char a-z0-9 after the dot.


To get all 4 matches, you can make the first group optional using *

@(?:[a-z0-9-]+\.)*[a-z0-9]+

Regex demo | Php demo

Note that you don't have to escape the \@ and that you can repeat the character class itself [a-z0-9]+ instead of matching a single char in a capture group and then repeat the group.

Example code

$txt = "Testando se essa pescaria é valida @ju1lio.leao, se não for aciona @alycianne.
Importante deixar @mirian ciente. E a @simone.akemi de sobreaviso.";
$pattern = "/@(?:[a-z0-9-]+\.)*[a-z0-9]+/";
preg_match_all($pattern, $txt, $matches);
print_r($matches[0]);

Output

Array
(
    [0] => @ju1lio.leao
    [1] => @alycianne
    [2] => @mirian
    [3] => @simone.akemi
)

You can use only one pattern:

$pattern = '/\@[a-z0-9-]+(?:\.?[a-z0-9-]+)/';
Related