【问题标题】:How do I replace custom "tags" in a string?如何替换字符串中的自定义“标签”?
【发布时间】:2018-09-21 22:51:19
【问题描述】:

鉴于以下情况:

$foo = "Yo [user Cobb] 我听说你喜欢做梦,所以我在你的梦中放了一个梦,这样你就可以一边做梦一边做梦。"

我想这样做:

$foo = bar($foo);

回声 $foo;

得到这样的东西:

Cobb听说你喜欢做梦,所以我把一个梦放在你的梦里,这样你就可以一边做梦一边做梦。

我不确定bar 函数应该如何工作。我认为这对正则表达式是可行的,但我个人觉得这些很难理解。使用strpos函数是另一种方法,但我想知道是否有更好的解决方案。

伪代码很好,但实际代码将不胜感激。

编辑:

这些标签不是占位符,因为第二部分是一个变量值。

编辑:

所有 str_replace 答案都不正确,因为标签包含可变内容。

【问题讨论】:

  • 是否有用于格式化的自定义打开和关闭标签(如 BBCodes),或者这些只是用于将某些字符串替换为其他字符串的占位符?
  • @dqhendricks:感谢您提醒我回答这个问题。我更新了我的问题。
  • 即使替换是一个变量,它仍然是一个简单的占位符被一个值替换对吧?或者是否有用于格式化它们之间的内容的打开和关闭标签,如 BBCodes?意思是,[b]formatted string[/b] 将被替换为 formatted string 之类的东西。
  • 是否有带有参数的标签,例如 [url=www.example.com]example[/url]?
  • @dqhendricks:我希望使用的格式是:[foo bar]。例如:[user Cobb][news 12]

标签: php


【解决方案1】:

您可以使用 preg_match_all 在字符串中搜索标签。

function bar($foo)
{
    $count = preg_match_all("/\[(\w+?)\s(\w+?)\]/", $foo, $matches);
    if($count > 0)
    {
         for($i = 0; $i < $count; $i++)
         {
             // $matches[0][$i] contains the entire matched string
             // $matches[1][$i] contains the first portion (ex: user)
             // $matches[2][$i] contains the second portion (ex: Cobb)

             switch($matches[1][$i])
             {
                 case 'user':
                     $replacement = tag_user($matches[2][$i]);
                     str_replace($matches[0][$i], $replacement, $foo);
                     break;
             }
         }
    }
}

现在您可以通过向开关添加更多案例来添加更多功能。

【讨论】:

    【解决方案2】:

    由于标签包含您要解析的内容并且不是静态的要替换的标签,因此您必须使用正则表达式。 (这是最简单的方法。)

    preg_replace()是替换文本的正则表达式函数。

    $pattern = '/\[user (\w+)\]/i';
    $rpl     = '<a href="http://example.com/user/${1}">${1}</a>';
    return preg_replace($pattern, $rpl, $foo);
    

    这将匹配一个 [user xy] 标签,其中 xy 是至少一个字符的单词(单词字符序列)。因为它在括号中,所以可以使用替换字符串中的 {1} 访问它。 $foo 是您要解析的字符串。返回的是带有替换标签的解析字符串。模式上的 i 修饰符将使匹配不区分大小写。如果您希望它区分大小写,请将其删除。


    (您给出的示例从 [user Cobb] 解析为 wikipedia url leonardo dicabrio,这与 userCobb 都没有对应关系。所以无论你到达那里,你都必须这样做(查询数据库? 随便)。如果只是提供示例代码不够小心;您可能想指向一个静态 url 并向其中添加部分标记内容,这就是我在这里所做的。)

    【讨论】:

      【解决方案3】:

      str_replace() 将是您的最佳选择:

      function bar($foo) {
         $user = 'Cobb';
         return str_replace('[user]', $user, $foo);
      }
      
      $foo = 'Yo [user] I heard you like dreams so I put a dream in yo dream in yo dream so you can dream while you dream while you dream.'
      $foo = bar($foo);
      print $foo; // Will print "Yo Cobb I heard you like dreams so I put a dream in yo dream in yo dream so you can dream while you dream while you dream."
      

      【讨论】:

        【解决方案4】:

        str_replace 呢?

        function bar(foo)
        return str_replace($arrayWithStringsToGetReplaced,
                           $arrayWithStringsToReplaceWith,
                           $foo)
        

        如果我理解下面的 cmets 正确。

        这显然超出了我的范围。继续... :)

        【讨论】:

        • 不确定如何使用开关,但实际上可以将 str_replace 数组作为搜索字符串和替换字符串的参数传递。
        • 您当然是对的,我在看到您的评论之前就意识到了我的错误。传递双数组听起来不错,但结果将是一个数组,对吧?
        • 不完全是,结果是一个字符串,每个单独的字符串替换都在它上面执行。
        • 啊!并且这两个数组需要对齐,所以 replacerArr[0] 必须是 replaceeArr[0] 的替换字符串?
        【解决方案5】:

        Regular Expressions 是要走的路。很难,但是学习它们所获得的好处远远超过学习所需的努力。

        来自php.net

        <?php
        $text = 'The price is PRICE ';
        
        $lookFor = 'PRICE';
        $replacement = '$100';
        
        echo $replacement.'<br />';
        //will display
        //$100
        
        
        echo str_replace($lookFor, $replacement, $text).'<br />';
        //Will display
        //The price is $100
        ?>
        

        【讨论】:

        • 您必须在每行代码之前手动放置 4 个空格,否则将不会被接受为代码标签
        • 还有,这不是正则表达式,好像你只是撕掉了一些代码
        猜你喜欢
        • 1970-01-01
        • 2014-05-08
        • 1970-01-01
        • 2021-03-30
        • 2020-01-12
        • 2016-07-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多