【问题标题】:Check the word after a '@' character in PHP检查PHP中'@'字符后的单词
【发布时间】:2012-12-12 03:48:15
【问题描述】:

我现在正在制作一个新闻和评论系统,但我现在被困在一个部分上一段时间了。我希望用户能够以 @username 之类的 twitter 样式引用其他玩家。脚本看起来像这样:(不是真正的 PHP,只是想象脚本;3)

$string = "I loved the article, @SantaClaus, thanks for writing!";
if($string contains @){ 
    $word = word after @;
    $check = is word in database? ...
}

对于字符串中的所有@username,可能使用while() 来完成。我卡住了,请帮忙。

【问题讨论】:

  • 在这种情况下,RegEx 没有问题,您可能需要检查preg_match()
  • 传闻人们称之为伪代码
  • @Alexander - 不过我有点喜欢。 Imagination 脚本。 “你做什么工作,Alex?” “想象力脚本。”O_o'

标签: php character


【解决方案1】:

看起来像是 preg_replace_callback() 的工作:

$string = preg_replace_callback('/@([a-z0-9_]+)/', function ($matches) {
  if ($user = get_user_by_username(substr($matches[0], 1)))
    return '<a href="user.php?user_id='.$user['user_id'].'">'.$user['name'].'</a>';
  else
    return $matches[0];
}, $string);

【讨论】:

  • +1 这当然可行,但可能会使新开发人员感到困惑。可维护性很重要。这可以在没有晦涩的函数和正则表达式的情况下完成。但是一个中的 6 个,另一个是 6 个。
  • 我不同意。正则表达式和函数(甚至是匿名的)并不晦涩难懂。事实上,我发现这比您的解决方案更清晰(因为 意图 对于懂语言的人来说是显而易见的)。
  • 我希望大多数代码都是由懂语言的人维护的。如果你的继任者不懂语言,你可能认为这不是你的错,但重要的是他们是否能理解代码。但我同意,每个人都应该知道这些事情。
【解决方案2】:

这就是正则表达式的用武之地。

<?php
    $string = "I loved the article, @SantaClaus! And I agree, @Jesus!";
    if (preg_match_all('/(?<!\w)@(\w+)/', $string, $matches))
    {
        $users = $matches[1];
        // $users should now contain array: ['SantaClaus', 'Jesus']
        foreach ($users as $user)
        {
            // check $user in database
        }
    }
?>
  1. 开头和结尾的/分隔符(暂时不用担心这些)。
  2. \w 代表单词字符,包括a-zA-Z0-9_
  3. (?&lt;!\w)@ 有点高级,但它被称为否定的后向断言,意思是“@跟在单词字符后面。 "这样您就不会包含电子邮件地址之类的内容。
  4. \w+ 表示“一个或多个单词字符”。 + 被称为量词
  5. \w+ 周围的括号捕获括号中的部分,并出现在$matches 中。

regular-expressions.info 似乎是一个受欢迎的教程选择,但网上还有很多其他的。

【讨论】:

    【解决方案3】:

    考虑使用 Twitter API 从您的文本中获取用户名:https://github.com/twitter/twitter-text-js

    【讨论】:

    • 对于 OP 来说可能有点笨拙,但考虑到现有解决方案 +1。
    【解决方案4】:

    这是一个符合您需要的表达式,但不会捕获电子邮件地址:

    $str = '@foo I loved the article, @SantaClaus, thanks for writing to my@email.com';
    preg_match_all('/(^|[^a-z0-9_])(@[a-z0-9_]+)/i', $str, $matches);
    //$matches[2][0] => @foo
    ///$matches[2][1] => @SantaClause
    

    如您所见:my@email.com 未被捕获,但@foo 和@SantaClaus 字符串...

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多