Most of the time we use ‘@’ to mention someone’s name in email thread, forum, etc. How about to find those mentioned names using PHP regular expression? Let’s consider the following text.
“Hey @Junal how about going for a vacation to @Srimangal? @Jewel said it’s an awesome place”
We will find all names that is mentioned by @ here. So let’s write the pattern first.
$pattern = “/^(?:[a-zA-Z0-9?. ]?)+@([a-zA-Z0-9]+)(.+)?$/”;
See, first portion of the pattern is optional, some one can start your name @junal or hey @junal right. And then we are matching with ‘@’ separating them from @ sign. Rest portion of the patter is quite easy, as we can keep text after the name (I.e @junal you suck)
Ok, now let’s use the php preg_match() function to find the matches. If we find the matched it will return 1 else 0.
$pattern = "/^(?:[a-zA-Z0-9?. ]?)+@([a-zA-Z0-9]+)(.+)?$/"; $str = "Hey @Junal hey how are you?"; preg_match($pattern, $str, $matches); print_r($matches); //Output : Array ( [0] => Hey @Junal hey how are you? [1] => Junal [2] => hey how are you? )
So, if we want to find first matched name then it’s pretty straight forward to get it from $matches[1]
but what if we want to find multiple name from a text? Well, then we have to search $matches[2] if there is anymore mentioned name wit @ right?… let’s do it this way…
do { preg_match($pattern, $matches[2], $more_matches); $name_list[$counter++] = $more_matches[1]; $count = count($more_matches); $matches[2]=$more_matches[($count-1)]; $more_matches = ""; } while($count>=3);
this above code might be confusing. So let’s see the complete function that returns us an array of names that are mentioned by ‘@’ and well, we will also remove the duplicate names.
< ?php /* * isn't the name self explanatory ? */ function giveme_names_from_at($str) { $pattern = "/^(?:[a-zA-Z0-9?. ]?)+@([a-zA-Z0-9]+)(.+)?$/"; $str = trim($str); preg_match($pattern, $str, $matches);; if($matches) { $counter = 0; $name_list = array(); $name_list[$counter++] = $matches[1]; do { preg_match($pattern, $matches[2], $more_matches); $name_list[$counter++] = $more_matches[1]; $count = count($more_matches); $matches[2]=$more_matches[($count-1)]; $more_matches = ""; } while($count>=3); if(!empty($name_list)) { $all_names = array(); $i = 0; foreach ($name_list as $key => $value) { if (!is_null($value) && (!in_array($value, $all_names))) { $all_names[$i] = $value; $i++; } } } return $all_names; } } //Example $str = "Hey @Junal how about going for a vacation to @Srimangal? @Jewel said it's an awesome place"; $names = giveme_names_from_at($str) print_r($names); //Output: Array ( [0] => Junal [1] => Srimangal [2] => Jewel ) ?>
Ok well, output shows what we needed. But using regular expression is not always a good idea as it’s slower than standard string manipulation functions. How would you like to find these answers without using RE? Or can we improve this pattern to make It smarter?

