Welcome to the Question2Answer Q&A. There's also a demo if you just want to try it out.
+1 vote
989 views
in Plugins by

I want to get user's handles that start @(atmark) from certain text with regular expression (preg_match_all).

E.G.

Text example: @usera aaa bbb @userb ccc ddd eee @userc fff ggg

Result example: @usera, @userb, @userc

Best regards.

1 Answer

+4 votes
by
selected by
 
Best answer

The question and example are very tricky! :) Basically, you can't. This is because it is valid to use spaces in Q2A in handles. That means from a given text such as:

@usera aaa bbb @userb ccc ddd eee @userc fff ggg

You could have 3 valid handles like these too: @usera aaa, @userb, @userc fff ggg

Now, assuming you're not allowing spaces in your handles you could use this regex: /@[^\s@\/\+]+/g

See this link: https://regex101.com/r/bN8kF0/1

This approach allows all characters to be part of handles but reject white spaces characters, ats, slashes and plus signs (as the core does). Additional filtering rules will depend on your configuration.

by
+1 Thank you puti1985. Your answer is useful for me. I refer to your code, and a little more testing. I will report the results in after.
Thanks again.
by
Finally, I adopted regex("/@[^\s@\/]+/") for preg_match_all().
Reason that I excluded "\+": Q2A allows space to user handle.
If user handle contains space, we connect words with "+" character.
e.g. "John Doe" >>>"@John+Doe"

Reference information:

This is a function to get array of userid at q_post / a_post / c_post / q_edit / a_edit / c_edit event.
I hope this will be useful for someone.

    function mention($event, $userid, $handle, $cookieid, $params) {
        $userids = array();
       
        $regularex = "/@[^\s@\/]+/";
       
        $type = explode("_", $event);
        $post_types = Array("q", "a", "c");
        $event_types = Array("post", "edit");
       
        if (!in_array($type[0], $post_types) or !in_array($type[1], $event_types))
            return $userids;
        if(!array_key_exists('text', $params))
            return $userids;
       
        $tohandles = Array();
        if(isset($params["title"])) {
            if(preg_match_all($regularex, $params["title"], $matches)) {
                foreach ($matches[0] as $matche) {
                    $item = trim($matche, "@ \t\n\r\0\x0B");
                    $item = str_replace('+', ' ', $item);
                    if (!in_array($item, $tohandles))
                        $tohandles[] = $item;
                }
            }
        }
        if(!empty($params["text"])) {
            if(preg_match_all($regularex, $params["text"], $matches)) {
                foreach ($matches[0] as $matche) {
                    $item = trim($matche, "@ \t\n\r\0\x0B");
                    $item = str_replace('+', ' ', $item);
                    if (!in_array($item, $tohandles))
                        $tohandles[] = $item;
                }
            }
        }
        if(count($tohandles)) {
            $userids = qa_handles_to_userids($tohandles);
            foreach($userids as $handle => $userid) {
                if(empty($userid))
                    unset($userids[$handle]);
            }
        }
        return $userids;
    }

Thanks again.
by
Welcome! Thanks for sharing the code. It can be handy!
...