PHP 提及系统,用户名带有空格

我想知道是否可以制作一个带有空格的用户名的 PHP 提及系统?我试过这个


preg_replace_callback('#@([a-zA-Z0-9]+)#', 'mentionUser', htmlspecialchars_decode($r['content']))

我的功能:


    function mentionUser($matches) {

    global $db;

    $req = $db->prepare('SELECT id FROM members WHERE username = ?');

    $req->execute(array($matches[1]));


    if($req->rowCount() == 1) {

        $idUser = $req->fetch()['id'];

        return '<a class="mention" href="members/profile.php?id='.$idUser.'">'.$matches[0].'</a>'; 

    }

    return $matches[0]; 

它有效,但不适用于带空格的用户名...我尝试添加\s,它有效,但效果不佳, preg_replace_callback 检测用户名和消息的其他部分,因此不会出现提及...有吗有什么解决办法吗?谢谢 !


慕码人8056858
浏览 127回答 2
2回答

白衣染霜花

我知道您说过您刚刚删除了添加空格的功能,但我仍然想发布解决方案。需要明确的是,我不一定认为您应该使用此代码,因为它可能更容易使事情变得简单,但我认为它仍然应该有效。您的主要问题是,几乎每次提及都会引起两次查找,因为@bob johnson went to the store可能是bob或bob johnson,并且如果不访问数据库就无法确定这一点。幸运的是,缓存将大大减少这个问题。下面是一些通常可以完成您正在寻找的操作的代码。为了清晰和可重复性,我仅使用数组制作了一个假数据库。内联代码注释应该是有意义的。function mentionUser($matches){&nbsp; &nbsp; // This is our "database" of users&nbsp; &nbsp; $users = [&nbsp; &nbsp; &nbsp; &nbsp; 'bob johnson',&nbsp; &nbsp; &nbsp; &nbsp; 'edward',&nbsp; &nbsp; ];&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; // First, grab the full match which might be 'name' or 'name name'&nbsp; &nbsp; $fullMatch = $matches['username'];&nbsp; &nbsp; // Create a search array where the key is the search term and the value is whether or not&nbsp; &nbsp; // the search term is a subset of the value found in the regex&nbsp; &nbsp; $names = [$fullMatch => false];&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; // Next split on the space. If there isn't one, we'll have an array with just a single item&nbsp; &nbsp; $maybeTwoParts = explode(' ', $fullMatch);&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; // Basically, if the string contained a space, also search only for the first item before the space,&nbsp; &nbsp; // and flag that we're using a subset&nbsp; &nbsp; if (count($maybeTwoParts) > 1) {&nbsp; &nbsp; &nbsp; &nbsp; $names[array_shift($maybeTwoParts)] = true;&nbsp; &nbsp; }&nbsp; &nbsp; foreach ($names as $name => $isSubset) {&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; // Search our "database"&nbsp; &nbsp; &nbsp; &nbsp; if (in_array($name, $users, true)) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // If it was found, wrap in HTML&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $ret = '<span>@' . $name . '</span>';&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // If we're in a subset, we need to append back on the remaining string, joined with a space&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if ($isSubset) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $ret .= ' ' . array_shift($maybeTwoParts);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return $ret;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; // Nothing was found, return what was passed in&nbsp; &nbsp; return '@' . $fullMatch;}// Our search pattern with an explicitly named capture$pattern = '#@(?<username>\w+(?:\s\w+)?)#';// Three testsassert('hello <span>@bob johnson</span> test' === preg_replace_callback($pattern, 'mentionUser', 'hello @bob johnson test'));assert('hello <span>@edward</span> test' === preg_replace_callback($pattern, 'mentionUser', 'hello @edward test'));assert('hello @sally smith test' === preg_replace_callback($pattern, 'mentionUser', 'hello @sally smith test'));

猛跑小猪

试试这个正则表达式:/@[a-zA-Z0-9]+(&nbsp;*[a-zA-Z0-9]+)*/g它会首先找到一个 at 符号,然后尝试找到一个或多个字母或数字。它将尝试找到零个或多个内部空格以及其后的零个或多个字母和数字。我假设用户名仅包含 A-Za-z0-9 和空格。
打开App,查看更多内容
随时随地看视频慕课网APP