2 回答
TA贡献1796条经验 获得超10个赞
我知道您说过您刚刚删除了添加空格的功能,但我仍然想发布解决方案。需要明确的是,我不一定认为您应该使用此代码,因为它可能更容易使事情变得简单,但我认为它仍然应该有效。
您的主要问题是,几乎每次提及都会引起两次查找,因为@bob johnson went to the store可能是bob或bob johnson,并且如果不访问数据库就无法确定这一点。幸运的是,缓存将大大减少这个问题。
下面是一些通常可以完成您正在寻找的操作的代码。为了清晰和可重复性,我仅使用数组制作了一个假数据库。内联代码注释应该是有意义的。
function mentionUser($matches)
{
// This is our "database" of users
$users = [
'bob johnson',
'edward',
];
// First, grab the full match which might be 'name' or 'name name'
$fullMatch = $matches['username'];
// Create a search array where the key is the search term and the value is whether or not
// the search term is a subset of the value found in the regex
$names = [$fullMatch => false];
// Next split on the space. If there isn't one, we'll have an array with just a single item
$maybeTwoParts = explode(' ', $fullMatch);
// Basically, if the string contained a space, also search only for the first item before the space,
// and flag that we're using a subset
if (count($maybeTwoParts) > 1) {
$names[array_shift($maybeTwoParts)] = true;
}
foreach ($names as $name => $isSubset) {
// Search our "database"
if (in_array($name, $users, true)) {
// If it was found, wrap in HTML
$ret = '<span>@' . $name . '</span>';
// If we're in a subset, we need to append back on the remaining string, joined with a space
if ($isSubset) {
$ret .= ' ' . array_shift($maybeTwoParts);
}
return $ret;
}
}
// Nothing was found, return what was passed in
return '@' . $fullMatch;
}
// Our search pattern with an explicitly named capture
$pattern = '#@(?<username>\w+(?:\s\w+)?)#';
// Three tests
assert('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'));
TA贡献1858条经验 获得超8个赞
试试这个正则表达式:
/@[a-zA-Z0-9]+( *[a-zA-Z0-9]+)*/g
它会首先找到一个 at 符号,然后尝试找到一个或多个字母或数字。它将尝试找到零个或多个内部空格以及其后的零个或多个字母和数字。
我假设用户名仅包含 A-Za-z0-9 和空格。
- 2 回答
- 0 关注
- 126 浏览
添加回答
举报