2 回答

TA貢獻1796條經驗 獲得超10個贊
我知道您說過您剛剛刪除了添加空格的功能,但我仍然想發布解決方案。需要明確的是,我不一定認為您應該使用此代碼,因為它可能更容易使事情變得簡單,但我認為它仍然應該有效。
您的主要問題是,幾乎每次提及都會引起兩次查找,因為@bob johnson went to the store可能是bob或bob johnson,并且如果不訪問數據庫就無法確定這一點。幸運的是,緩存將大大減少這個問題。
下面是一些通??梢酝瓿赡趯ふ业牟僮鞯拇a。為了清晰和可重復性,我僅使用數組制作了一個假數據庫。內聯代碼注釋應該是有意義的。
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 關注
- 162 瀏覽
添加回答
舉報