Welcome to the Question2Answer Q&A. There's also a demo if you just want to try it out.

Do you know regular expression pattern for getting user handle?

+1 vote
455 views
asked Jan 28, 2015 in Plugins by sama55

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
answered Jan 28, 2015 by pupi1985
selected Jan 28, 2015 by sama55
 
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.

commented Jan 28, 2015 by sama55
+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.
commented Jan 28, 2015 by sama55
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.
commented Jan 28, 2015 by pupi1985
Welcome! Thanks for sharing the code. It can be handy!
...