【问题标题】:preg replace_callback mentions and hashtags in postpreg replace_callback 在帖子中提及和主题标签
【发布时间】:2012-12-23 21:33:54
【问题描述】:

假设我有一个文本,

$text = '@stackguy @flowguy I need to learn more advanced php #ilovephp';

我想分别用这两个锚标签替换@stackguy 和@flowguy。这也适用于文本字符串中任意数量的@。

<a href="url/stackguy">@stackguy</a>
<a href="url/flowguy">@flowguy</a>

我也想用

替换#ilovephp
<a href="search/ilovephp">#ilovephp</a>

它也应该适用于多个#。我猜会是这样的

preg_replace_callback('regex',
            create_function('$matches', '
                switch ($matches[1]) {
                    case "@":
                        return "<a href=url.$matches[2]'/'>" . $matches[2] . "</a>";
                    case "#":
                        return "<a>" . $matches[2] . "</a>";
                }
        '), $var);

正则表达式会是什么样子? 我的函数是要匹配所有需要的还是我需要添加一个 foreach 循环? 谢谢。

【问题讨论】:

  • Sooo...有什么问题?
  • 你为什么“猜测它会是这样的”?尝试一下,然后如果它不起作用,那么我们有一些事情要做。您已经接近实际编写一些代码并进行尝试了。
  • func(正则表达式)最重要的部分是我不知道的。

标签: php regex preg-replace preg-replace-callback


【解决方案1】:

tutorial on replacing hashtags and mentions 之后,preg_replace() 就足够了。

$patterns = array('/#(\w+)/', '/@(\w+)/');
$replacements = array('<a href="http://example.com/tag/$1">#$1</a>', 
                '<a href="http://example.com/user/$1">@$1</a>');

$html = preg_replace($patterns, $replacements, $text);

【讨论】:

    【解决方案2】:

    preg_replace()preg_replace_callback() 默认情况下都会查找所有可能的匹配项,因此您不需要循环。

    考虑到这些值还没有被锚包裹,我会使用任何一个

    preg_replace('~@([^\s#@]+)~','<a href="url/\1">$0</a>',
        preg_replace('~#([^\s#@]+)~','<a href="search/\1">$0</a>',$text)
    );
    

    preg_replace_callback('~([#@])([^\s#@]+)~',create_function('$m',
        '$dir = $m[1] == "#" ? "search" : "url";' .
        'return "<a href=\"$dir/$m[2]\">$m[0]</a>";'
    ),$text);
    

    【讨论】:

      【解决方案3】:

      如果您不想匹配前面有 @ 或 # 的文本,请使用:/([@#])(\S+)/

      查看此演示:http://regex101.com/r/eP7eU0

      注意:当它在标签内时,它会匹配相同的东西。如果你不想这样,你需要的不仅仅是正则表达式。

      【讨论】:

      • 可能想将其修改为/([@#])(\S+)/。 Saffron 需要匹配符号以确定将其包裹在哪个锚标记中。
      • 谢谢@lindrian 和 Gigawatt:这个函数是全部替换还是我需要一个循环?
      • @SaffronHarris:preg_replace() 自动循环,您不必自己这样做。
      • @lindrian:在标签内匹配相同的东西是什么意思?你的意思是如果我有

        相同的文本

        ,它会输出相同的结果?
      • @SaffronHarris 不,这不会影响正常情况。 \S 表示“除了任何类型的空格之外的任何内容”,因此如果您确定只想匹配,比如字母数字字符,那么您可以使用\w 而不是\S[^\s#@]。请注意,\w(单词字符)匹配 a-z、A-Z、0-9 和下划线 (_)。您始终可以将其限制为您想要的字符组,例如 [a-zA-Z][a-zA-Z0-9] 等。无论如何不要忘记加号以捕获尽可能多的字符,就像 Lindrian 的建议一样。
      猜你喜欢
      • 2016-06-20
      • 2017-04-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-12-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多