【问题标题】:very simple preg_replace not working非常简单的 preg_replace 不起作用
【发布时间】:2013-09-03 16:09:29
【问题描述】:
function emotify($text)
{
    $icons = array(
                ':)'    =>  '<img src="/images/emoticons/happy.png" alt="smile" class="icon_smile" />',
                ':-)'   =>  '<img src="/images/emoticons/happy.png" alt="smile" class="icon_smile" />',
                ':D'    =>  '<img src="/images/emoticons/grin.png" alt="smile" class="icon_laugh" />',
                ':d'    =>  '<img src="/images/emoticons/grin.png" alt="laugh" class="icon_laugh" />',
                ":'("    =>  '<img src="/images/emoticons/crying.png" alt="crying" class="icon_cry" />',
                ';('    =>  '<img src="/images/emoticons/crying.png" alt="crying" class="icon_cry" />',
                ':d'    =>  '<img src="/images/emoticons/grin.png" alt="laugh" class="icon_laugh" />',
                ';)'    =>  '<img src="/images/emoticons/wink.png" alt="wink" class="icon_wink" />',
                ':P'    =>  '<img src="/images/emoticons/tounge.png" alt="tounge" class="icon_tounge" />',
                ':-P'   =>  '<img src="/images/emoticons/tounge.png" alt="tounge" class="icon_tounge" />',
                ':-p'   =>  '<img src="/images/emoticons/tounge.png" alt="tounge" class="icon_tounge" />',
                ':p'    =>  '<img src="/images/emoticons/tounge.png" alt="tounge" class="icon_tounge" />',
                ':('    =>  '<img src="/images/emoticons/sad.png" alt="sad face" class="icon_sad" />',
                ':-('   =>  '<img src="/images/emoticons/sad.png" alt="sad face" class="icon_sad" />',
                ':o'    =>  '<img src="/images/emoticons/shocked.png" alt="shock" class="icon_shock" />',
                ':O'    =>  '<img src="/images/emoticons/shocked.png" alt="shock" class="icon_shock" />',
                ':0'    =>  '<img src="/images/emoticons/shocked.png" alt="shock" class="icon_shack" />',
                ':|'    =>  '<img src="/images/emoticons/straight.png" alt="straight face" class="icon_straight" />',
                ':-|'   =>  '<img src="/images/emoticons/straight.png" alt="straight face" class="icon_straight" />',
                ':/'    =>  '<img src="/images/emoticons/straight.png" alt="straight face" class="icon_straight" />',
                ':-/'   =>  '<img src="/images/emoticons/straight.png" alt="straight face" class="icon_straight" />'
        );

     foreach($icons as $icon=>$image) {
      $icon = preg_quote($icon, '/');
$return = preg_replace("/$icon/i", $image, $text);
      }
    return $return;
}
$posted = emotify($posted);

这是我将表情符号转换为图像的代码。它只是返回
Warning: preg_replace(): Unknown modifier '/' on line 203

我该如何解决? 编辑:这是我的所有代码,包括数组,这可能是我的代码无法正常工作的问题。我不确定,但没有一个答案有帮助,所以我认为这一定是问题所在。

【问题讨论】:

标签: php preg-replace


【解决方案1】:

通过 cmets 进一步确定了您正在做什么,这里是使用 DOM 解析器和一点聪明的答案:

$dom = new DOMDocument();
$dom->loadHTML($text);
$xpath = new DOMXPath($dom);
foreach($icons as $icon=>$image) {
  $textnodes = $xpath->query("//text()"); // get all text nodes
  foreach($textnodes as $node) {
    // the regex used here requires that there not be a non-space before it
    // in other words, it must be the first thing, or have a space before it
    while( preg_match("((?<!\S)".preg_quote($icon).")i",$node->nodeValue,$m,PREG_OFFSET_CAPTURE)) {
      $emote = $node->splitText($m[0][1]); // the offset is stored here
      $node = $emote->splitText(strlen($icon));
      // now replace the emote with the image:
      $img = $dom->createElement("img");
      $img->setAttribute("src",$image);
      // IMPORTANT: $image must be just the SRC, and NOT the entire HTML node
      $emote->parentNode->replaceChild($img,$emote);
    }
  }
}
// loadHTML puts the HTML into a document, we need to get it back out
$result = $dom->saveHTML($dom->getElementsByTagName('body')->item(0));
$result = substr($result,strlen("<body>"),-strlen("</body>"));

现在你可以使用$result,它应该有有效的HTML,包括转换后的表情。

【讨论】:

  • 所以这仍然在 php 中
  • 所以如果我把这段代码放到我的 emotify 函数中它应该可以工作吗?
  • 是的,只要您按照代码的 cmets 中所述调整您的 $icons 数组。
  • 致命错误:调用未定义的方法 DOMNode::setAttribute()
  • 啊,我错了,应该是new DOMElement,而不是new DOMNode。
【解决方案2】:

$icon 的值中可能有一个斜线,所以你实际上是在调用

preg_replace( '/foo/bar/i', $image, $text )

这是一个错误。

【讨论】:

    【解决方案3】:

    preg_quote 不会转义斜杠,除非你告诉它这是你选择的分隔符。

    话虽如此,使用 PREG 实在是太过分了。

    请改用str_ireplace。

    【讨论】:

    • 那你就得聪明一点了。避免使用可能出现在合法文本中的笑脸代码。我个人更喜欢=/ 而不是:/。当然,我也会质疑你是否想要表情。你在聊天吗?如果没有,您可能不想要它们。
    • 是的,我正在聊天,我从这里偷了我问题中的代码
    • 考虑在 JavaScript 端替换它们。 JavaScript 比 PHP 更容易区分文本和非文本。
    • 这行不通,因为聊天记录在数据库中,并且在 php 中被删除了 html 标签
    【解决方案4】:

    preg_quote 实际上有 2 个参数。第二个可选参数可以是在preg functions 中使用的regex delimiter。

    按照说明书:

    delimiter

    If the optional delimiter is specified, it will also be escaped. This is useful for escaping the delimiter that is required by the PCRE functions. The / is the most commonly used delimiter.

    像这样使用你的代码:

    $icon = preg_quote($icon, '/');
    $return = preg_replace("/$icon/i", $image, $text);
    

    更新:问题是您没有在 foreach 循环开始之前初始化 $return 变量,并且总是尝试替换原始 $text 变量本身。

    让你的 foreach 循环像这样:

    $return = $text;
    foreach($icons as $icon=>$image) {
           $icon = preg_quote($icon, '/');
           $return = preg_replace("/$icon/i", $image, $return);
    }
    

    【讨论】:

    • 那不工作也许是我的数组我会在问题中发布它
    • @jordanzhninja:进一步编辑以允许在输入中进行多次替换,例如这个输入现在也应该可以工作了:" :D yey :)"
    【解决方案5】:

    你可以这样做:

    function emotify($text)
    {
        $icons = array(
            ':)'    =>  '<img src="/images/emoticons/happy.png" alt="smile" class="icon_smile" />',
            ':-)'   =>  '<img src="/images/emoticons/happy.png" alt="smile" class="icon_smile" />',
            ':D'    =>  '<img src="/images/emoticons/grin.png" alt="smile" class="icon_laugh" />',
            ':d'    =>  '<img src="/images/emoticons/grin.png" alt="laugh" class="icon_laugh" />',
            ':\'('  =>  '<img src="/images/emoticons/crying.png" alt="crying" class="icon_cry" />',
            ';('    =>  '<img src="/images/emoticons/crying.png" alt="crying" class="icon_cry" />',
            ';)'    =>  '<img src="/images/emoticons/wink.png" alt="wink" class="icon_wink" />',
            ':P'    =>  '<img src="/images/emoticons/tounge.png" alt="tounge" class="icon_tounge" />',
            ':-P'   =>  '<img src="/images/emoticons/tounge.png" alt="tounge" class="icon_tounge" />',
            ':-p'   =>  '<img src="/images/emoticons/tounge.png" alt="tounge" class="icon_tounge" />',
            ':p'    =>  '<img src="/images/emoticons/tounge.png" alt="tounge" class="icon_tounge" />',
            ':('    =>  '<img src="/images/emoticons/sad.png" alt="sad face" class="icon_sad" />',
            ':-('   =>  '<img src="/images/emoticons/sad.png" alt="sad face" class="icon_sad" />',
            ':o'    =>  '<img src="/images/emoticons/shocked.png" alt="shock" class="icon_shock" />',
            ':O'    =>  '<img src="/images/emoticons/shocked.png" alt="shock" class="icon_shock" />',
            ':0'    =>  '<img src="/images/emoticons/shocked.png" alt="shock" class="icon_shack" />',
            ':|'    =>  '<img src="/images/emoticons/straight.png" alt="straight face" class="icon_straight" />',
            ':-|'   =>  '<img src="/images/emoticons/straight.png" alt="straight face" class="icon_straight" />',
            ':/'    =>  '<img src="/images/emoticons/straight.png" alt="straight face" class="icon_straight" />',
            ':-/'   =>  '<img src="/images/emoticons/straight.png" alt="straight face" class="icon_straight" />'
            );
        return str_replace(array_keys($icons), array_values($icons), $text);
    }
    

    请注意,在这种情况下,最好定义两个数组。

    注意:这种搜索/替换不能区分大小写:D :d
    一个笑的表情是重复的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-07-17
      • 1970-01-01
      • 1970-01-01
      • 2016-03-26
      • 2012-11-03
      • 1970-01-01
      • 2021-04-30
      • 1970-01-01
      相关资源
      最近更新 更多