Php preg_replace 元素为数组

Php preg_replace with array in elements

我正在尝试做表情符号系统,如果数组中的元素穿过页面,则将值转到相反的一侧。示例:

 $emoticons = array(
      ':)'    =>  '<img src="assets/smiles/smilesblank.png" alt="smile" class="img-responsive" />',
      ':-)'   =>  '<img src="assets/smiles/smilesblank.png" alt="smile" class="icon_smile" />',
      ':D'    =>  '<img src="assets/smiles/smilesblank.png" alt="smile" class="icon_laugh" />',
      ':d'    =>  '<img src="assets/smiles/smilesblank.png" alt="laugh" class="icon_laugh" />',
      ';)'    =>  '<img src="assets/smiles/smilesblank.png" alt="wink" class="icon_wink" />',
      ':P'    =>  '<img src="assets/smiles/smilesblank.png" alt="tounge" class="icon_tounge" />',
      ':-P'   =>  '<img src="assets/smiles/smilesblank.png" alt="tounge" class="icon_tounge" />',
      ':-p'   =>  '<img src="assets/smiles/smilesblank.png" alt="tounge" class="icon_tounge" />',
      ':p'    =>  '<img src="assets/smiles/smilesblank.png" alt="tounge" class="icon_tounge" />',
      ':('    =>  '<img src="assets/smiles/smilesblank.png" alt="sad face" class="icon_sad" />',
      ':o'    =>  '<img src="assets/smiles/smilesblank.png" alt="shock" class="icon_shock" />',
      ':O'    =>  '<img src="assets/smiles/smilesblank.png" alt="shock" class="icon_shock" />',
      ':0'    =>  '<img src="assets/smiles/smilesblank.png" alt="shock" class="icon_shack" />',
      ':|'    =>  '<img src="assets/smiles/smilesblank.png" alt="straight face" class="icon_straight" />',
      ':-|'   =>  '<img src="assets/smiles/smilesblank.png" alt="straight face" class="icon_straight" />',
      ':/'    =>  '<img src="assets/smiles/smilesblank.png" alt="straight face" class="icon_straight" />',
      ':-/'   =>  '<img src="assets/smiles/smilesblank.png" alt="straight face" class="icon_straight" />'
 );
 foreach($emoticons as $icon => $image) {
      $icon = preg_quote($icon);
      $text = preg_replace("~\b$icon\b~",$image,$text);
 }

您可以使用preg_replace_callback_array

它使用模式数组->替换函数,与您的几乎相同。

我已经为你做了一个小例子:

<?php

// initial array
$emoticons = [
    ':)'    =>  '<img src="assets/smiles/smilesblank.png" alt="smile" class="img-responsive" />',
    ':-)'   =>  '<img src="assets/smiles/smilesblank.png" alt="smile" class="icon_smile" />',
    ':D'    =>  '<img src="assets/smiles/smilesblank.png" alt="smile" class="icon_laugh" />',
    ':d'    =>  '<img src="assets/smiles/smilesblank.png" alt="laugh" class="icon_laugh" />',
    ';)'    =>  '<img src="assets/smiles/smilesblank.png" alt="wink" class="icon_wink" />',
    ':P'    =>  '<img src="assets/smiles/smilesblank.png" alt="tounge" class="icon_tounge" />',
    ':-P'   =>  '<img src="assets/smiles/smilesblank.png" alt="tounge" class="icon_tounge" />',
    ':-p'   =>  '<img src="assets/smiles/smilesblank.png" alt="tounge" class="icon_tounge" />',
    ':p'    =>  '<img src="assets/smiles/smilesblank.png" alt="tounge" class="icon_tounge" />',
    ':('    =>  '<img src="assets/smiles/smilesblank.png" alt="sad face" class="icon_sad" />',
    ':o'    =>  '<img src="assets/smiles/smilesblank.png" alt="shock" class="icon_shock" />',
    ':O'    =>  '<img src="assets/smiles/smilesblank.png" alt="shock" class="icon_shock" />',
    ':0'    =>  '<img src="assets/smiles/smilesblank.png" alt="shock" class="icon_shack" />',
    ':|'    =>  '<img src="assets/smiles/smilesblank.png" alt="straight face" class="icon_straight" />',
    ':-|'   =>  '<img src="assets/smiles/smilesblank.png" alt="straight face" class="icon_straight" />',
    ':/'    =>  '<img src="assets/smiles/smilesblank.png" alt="straight face" class="icon_straight" />',
    ':-/'   =>  '<img src="assets/smiles/smilesblank.png" alt="straight face" class="icon_straight" />'
];

// prepare callbacks
$callbacks = [];
foreach ($emoticons as $smileCode => $replacement) {
    // regular expression, nothing smart, just plain replacement
    $regex = '~' . preg_quote($smileCode, '~') . '~';
    $callbacks[ $regex ] = function () use ($replacement) {
        return $replacement;
    };
}

$text = "Hello :), this is cool :P smile and :-| another one";

echo "<pre>\n";
echo preg_replace_callback_array($callbacks, $text);

在大多数情况下,匹配表情符号时不需要检查单词边界,因为它们通常粘在其他文本上。因此,\b 相当多余,可以删除。如果你真的只想针对特定的上下文,你可以考虑将第一个 \b 替换为 (?<!\w) (如果表情符号不能以单词 char 开头)并将第二个替换为 (?!\w) (后面没有字符),或分别使用空白边界 (?<!\S)(?!\S)

您可以按长度降序对数组的键进行排序(如果有重叠的表情符号,如:-||:-|),构建一个基于交替的正则表达式模式,而preg_quoteing 键,并使用 preg_replace_callback 将每个键替换为其对应的值:

array_multisort(array_map('strlen', array_keys($emoticons)), SORT_DESC, $emoticons);        //   IN DESCENDING ORDER
$pattern = '~' . implode("|", array_map(function($x) {return preg_quote($x, '~');}, array_keys($emoticons))) . '~';
echo preg_replace_callback($pattern, function($m) use ($emoticons) {
       return $emoticons[$m[0]];
    }, "Some :| emoticon :O");

参见 PHP demo,对于 "Some :| emoticon :O" 字符串,结果是

Some <img src="assets/smiles/smilesblank.png" alt="straight face" class="icon_straight" /> emoticon <img src="assets/smiles/smilesblank.png" alt="shock" class="icon_shock" />