0

我正在尝试创建一个类似于 Twitter 的系统来提及用户并在您被提及时接收通知。有很多问题在这里提出类似的问题,但似乎没有一个问题是决定性的并且以任何方式帮助我。

我的第一个麻烦是在发布状态时解析提及,它在某种程度上有效,但我不擅长需要使用的表达式。如果我发布了一个状态,例如说“@user1 hello there its @user2”,那么 user1 会正确解析,@ 是第一个字符,但我的 user2 将空格显示为解析的配置文件链接的一部分,这是我的 preg_replace 和表达式:

$STRING = preg_replace('/(^|\s)(@\w+)/','<a href="profile.php?u=$0">$0</a>', $STRING);

我还需要知道如何在配置文件链接中只显示不带 @ 的用户名,当前的 $0 也会产生 @ 符号。

至于通知,我有一个名为 alerts 的表,其结构如下:

编号 | 用户名 | 发送者 | 留言 | 已收到

message 字段包含通知消息的内容。我想知道如何从我提交的表单中提取任何提及并检查用户名是否存在,然后从那里为用户创建一个警报,告知他们在帖子中被提及。

4

3 回答 3

3

至于你的第一个正则表达式,你可以这样做:

$string = preg_replace('/(^|\s)@(\w+)/', '$1<a href="">$2</a>', $string);

这应该会为您提供没有初始空格或 @ 符号的用户名。基本上,我们将字符串的初始空间或开头捕获到一个变量中,并在替换的开头将其打印出来。您最终在 $2 中得到的只是@ 符号后面的内容。您也可以通过向后看来完成此操作,但我觉得这更简单。

至于您的数据库结构,也许这样的事情会做:

messages -
id | user_id | message

mentions -
message_id | user_id

对于每次提及,您将 user_id 插入到消息的表中。您可以选择是要实时发送警报还是等待批处理(或者可能 - 取决于性能要求 - 只需在需要时通过加入表来查询与提到的用户的帖子)。

于 2013-07-23T17:51:36.683 回答
3

我已经考虑这个问题几个小时了,虽然我有点新手,但我相信我有一种方法可以提取提及和警报并将它们存储到两个一维数组中。

    <?php
         //a variable ($string) that I thought might look like what you are describing
         $string='@steve how are you? @tom nice to hear from you. So happy that you joined @joe, cool! @mike sweeet!';
         //regex to pull out the mentions and the messages 
         preg_match_all('/@(\w+)|\s+([(\w+)\s|.|,|!|?]+)/', $string, $result, PREG_PATTERN_ORDER);
         for ($i = 0; $i < count($result[0]); $i++) {
            $mention[$i]= $result[1][$i];
            $message[$i]= $result[2][$i];
         }
         //test to make sure that all mentions are stored
         for ($j = 0; $j< $i; $j++){
            echo $mention[$j],'<br/>';
         }
         //test to make sure that all messages are stored
         for ($k = 0; $k< $j; $k++){
            echo $message[$k],'<br/>';
         }
    ?>

我使用的正则表达式的解释(由 Regex Buddy 提供):@(\w+)|\s+([(\w+)\s|.|,|!|?]+):

Match either the regular expression below (attempting the next alternative only if this one fails) «@(\w+)»
 Match the character “@” literally «@»
  Match the regular expression below and capture its match into backreference number 1 «(\w+)»
  Match a single character that is a “word character” (letters, digits, and underscores) «\w+»
  Between one and unlimited times, as many times as possible, giving back as needed (greedy) «+» 
 Or match regular expression number 2 below (the entire match attempt fails if this one fails to match) «\s([(\w+)\s|\.|,|!|?]+)»
Match a single character that is a “whitespace character” (spaces, tabs, and line breaks) «\s+»
 Between one and unlimited times, as many times as possible, giving back as needed (greedy) «+»
Match the regular expression below and capture its match into backreference number 2 «([(\w+)\s|\.|,|!|?]+)»
  Match a single character present in the list below «[(\w+)\s|\.|,|!|?]+»
     Between one and unlimited times, as many times as possible, giving back as needed (greedy) «+»
     The character “(” «(»
     A word character (letters, digits, and underscores) «\w»
     One of the characters “+)” «+)»
     A whitespace character (spaces, tabs, and line breaks) «\s»
     The character “|” «|»
     A . character «\.»
     One of the characters “|,!?” «|,|!|?»

这甚至会返回被括号偏移的消息中的单词(例如(hello))。您应该能够使用数组中定义的变量执行您描述的任何操作。如果这不正确,或者您无法做到,请告诉我,我会看看我能想出什么。

于 2013-07-23T21:52:40.713 回答
1

请查看本教程以使用 PHP、MYSQL 和 jQuery 实现 twitter 样式提及系统

您已使用正则表达式匹配从内容中提取 @提及

谢谢

于 2017-10-20T10:00:57.387 回答