PHP提及脚本

PHP提及脚本,php,Php,我正在编写一个提及脚本,当它在新闻文章或其他内容中被提及时,它会获得一个用户配置文件链接。我已经完成了提及脚本,但它在找到一个空格后会拆分用户名。当用户想要提及某人时,他们会以@符号开头 因此,我的脚本在找到一个空间后停止。这意味着如果我想提到一个用户名,比如@This is。它只会捡起这个 有人能告诉我怎样才能找到有空格的用户名吗?这是我的剧本 <?php $string = "I'm wanting to speak to the user @This is please.

我正在编写一个提及脚本,当它在新闻文章或其他内容中被提及时,它会获得一个用户配置文件链接。我已经完成了提及脚本,但它在找到一个空格后会拆分用户名。当用户想要提及某人时,他们会以@符号开头

因此,我的脚本在找到一个空间后停止。这意味着如果我想提到一个用户名,比如@This is。它只会捡起这个

有人能告诉我怎样才能找到有空格的用户名吗?这是我的剧本

    <?php

 $string = "I'm wanting to speak to the user @This is please.";
 $explosion = explode("@", $string);
 $count = count($explosion);

 for($i = 0; $i < $count; $i++){
    $explosion2 = explode(" ", $explosion[$i]);
    $explosion2 = $explosion2[0];

    $string = str_replace("@{$explosion2}", "{$explosion2} yeah", $string);
 }

 echo $string;
?>

您必须编辑此行:

$explosion2 = explode(" ", $explosion[$i]);
另一方面,它只会得到第一个字。如果您想将所有名称一直保留到一个点,请执行以下操作:

$explosion2 = explode(".", $explosion[$i]);

无法从示例中判断用户名是一个单词还是多个单词,因为用户名的格式与字符串的其余部分完全相同。有几种方法可以解决这个问题

你在@上爆炸,然后向上读,直到你到达用户名末尾的某个指示器。因此,需要对字符串进行修改,以便在用户名的开头和结尾都有特殊的指示符:

$string = "I'm wanting to speak to the user @This is@ please.";

这对您来说非常方便,因为您只需调用explode一次,因为整个用户名将位于数组的第二个元素中。

您不能这样做。通常用户名不包含空格。

您有办法查找用户名吗?我的意思是,您需要能够排除
这是
(甚至
这是请
),以便找到用户
这是
(如果这是预期用户)

天真的实现将提取
@
字符和用户名中无效的第一个字符(例如,
)之间的字符串。这将给出字符串
这是please
。然后你可以一次删掉一个单词,看看用户名是否匹配

但是,此策略不允许我在字符串
“@这不是我”中提及用户
如果用户
这是
存在

为了克服这个问题,应该明确提及用户名。这可以通过分隔符(字符本身不能是用户名的一部分)实现,例如:


也请参见。

如果有两个名为“This”和“This is”的用户,并且您有一条文本:“This is,您认为这是严重的吗?”


我的建议是不允许在用户名中使用空格。无论如何,在许多其他情况下(例如,URL创建),它可能会带来更多的麻烦。

您肯定需要使用回调,并需要一些方法来确定用户名是否存在。你不能单凭这些词就猜出来。为了简单起见,我更喜欢这里的regex回调:

$str= preg_replace_callback('/@(\w+)( \w+)?( \w+)?/', 'rx_users', $str);

function rx_users($match) {
    list($asis, $one, $two, $three) = $match;

    if (user_exists($user=$one)
    or  user_exists($user="$one$two")
    or  user_exists($user="$one$two$three"))
    {
        return "<a href=user/$user>$user</a>";
    }
    else return $asis;
}
$str=preg_replace_回调('/@(\w+)(\w+)(\w+)/,'rx_users',$str);
功能rx_用户($match){
列表($asis,$1,$2,$3)=$match;
如果(user_存在($user=$one)
或用户_存在($user=“$one$two”)
或用户_存在($user=“$1$2$3”))
{
返回“”;
}
否则返回$asis;
}

因此,如果没有
user\u exists()
测试,它将无法工作。但是你当然可以回过头来假设用户名是每个默认值一个单词。

我相信解决这个问题的办法是在注册时为每个注册用户分配一个唯一的数字标识符。 然后,每个用户都可以通过用户名和/或他们的真实姓名来引用,无论名字和第二个名字之间是否有空格


以@开头的字符串将启动对列表中所有用户的搜索,然后可以从类似facebook或twitter的下拉列表中进行选择。

我看到的问题是,您必须区分哪些空间不属于名称的一部分,哪些空间不属于名称的一部分。。。在您的示例中,如何区分名称是
这是
还是
这是请
。@约书亚:那么您不能两者兼得。有一种方法。我只是不知道。这个解决方案的问题是字符串是:
$string=“我想和用户说话@this is please。”
不是用户名的一部分。因此,脚本将获得不正确的(可能不存在的)用户。有一种方法,但正如我在回复中提到的,没有办法使其100%正确。即使使用,也需要对每种可能性进行额外的SQL查询。如果我的用户名是“m_i_n_g_o_s”(将下划线改为空格),那么算法将在数据库中查询“m”、“m_i”、“m_i_n”等。我认为这是一件浪费的事情。这并没有真正开始回答这个问题,IMHO。@jensgram,它是这样做的:不允许在用户名中使用空格。问题的解决方案并不总是你所期望的。@mingos在我看来,问题本身并不是空格字符。这是一个不明确的提及。我会用明确的提及代替,例如,
“我想和用户说话[这是]请。”
+1通过明确提及保持一致性。今天我可能会发现
@这是请
的行为和预期的一样(提到用户
这是
),但明天它可能会改变(如果用户
这是请
同时创建)。
$str= preg_replace_callback('/@(\w+)( \w+)?( \w+)?/', 'rx_users', $str);

function rx_users($match) {
    list($asis, $one, $two, $three) = $match;

    if (user_exists($user=$one)
    or  user_exists($user="$one$two")
    or  user_exists($user="$one$two$three"))
    {
        return "<a href=user/$user>$user</a>";
    }
    else return $asis;
}