问题
I am trying to do the emoji system and if the element in the array passes through the page, turn the value on the opposite side. Example:
$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);
}
回答1:
You can use preg_replace_callback_array
It uses array of patterns->replacement functions almost identical to yours.
I've made a little example for you:
<?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);
回答2:
In most cases, you do not need to check for a word boundary when matching emoticons as they are usually glued to some other text. Thus, \b
is rather redundant and can be removed. If you really want to only target specific contexts, you may consider replacing the first \b
with (?<!\w)
(if the emoticon cannot be preceded with a word char) and the second one with (?!\w)
(no word char after), or use whitespace boundaries, (?<!\S)
and (?!\S)
respectively.
You may sort the keys of the array by length in the descending order (in case there are overlapping emoticons, like :-||
and :-|
), build an alternation based regex pattern while preg_quote
ing the keys, and use a preg_replace_callback
to replace each key with its corresponding value:
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");
See the PHP demo, for the "Some :| emoticon :O"
string the result is
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" />
来源:https://stackoverflow.com/questions/47568806/php-preg-replace-with-array-in-elements