从字符串中删除 non-text 个字符(如表情符号)

Remove non-text chars (like emoticons) from string

如何替换字符串中的字符?有时 YouTube 视频标题包含这样的字符。我不想替换像 !@#$%^&*() 这样的字符。

我目前正在使用 preg_replace('/[^A-Za-z0-9\-]/', '', $VideoTitle);

样本数组:

$VideoTitles[]='Sia 2017 Cheap Thrills 2017 live '; 

$VideoTitles[]='TAYLOR SWIFT - SHAKE IT OFF  #1989'; 

预期输出:

Sia 2017 Cheap Thrills 2017 live 
TAYLOR SWIFT - SHAKE IT OFF #1989
function removeEmoticon($text) {

    $cleanText = "";

    // Match Emoticons
    $regexEmoticons = '/[\x{1F600}-\x{1F64F}]/u';
    $cleanText     = preg_replace($regexEmoticons, '', $text);

    // Match Miscellaneous Symbols and Pictographs
    $regexSymbols = '/[\x{1F300}-\x{1F5FF}]/u';
    $cleanText   = preg_replace($regexSymbols, '', $cleanText);

    // Match Transport And Map Symbols
    $regexTransport = '/[\x{1F680}-\x{1F6FF}]/u';
    $cleanText     = preg_replace($regexTransport, '', $cleanText);

    // Match Miscellaneous Symbols
    $regexMisc  = '/[\x{2600}-\x{26FF}]/u';
    $cleanText = preg_replace($regexMisc, '', $cleanText);

    // Match Dingbats
    $regexDingbats = '/[\x{2700}-\x{27BF}]/u';
    $cleanText    = preg_replace($regexDingbats, '', $cleanText);

    return $cleanText;
}

示例输入代码:Demo

$VideoTitles=[
    'Kilian à Dijon #4 • Vlog #2 • Primark again !?  - YouTube',
    'Funfesty   on Twitter: "Je commence à avoir mal à la tête à force',
    'Sia 2017 Cheap Thrills 2017 live '
];

$VideoTitles=preg_replace('/[^ -\x{2122}]\s+|\s*[^ -\x{2122}]/u','',$VideoTitles);  // remove out of range characters and whitespace character on one side only

var_export($VideoTitles);

输出:

array (
  0 => 'Kilian à Dijon #4 • Vlog #2 • Primark again !? - YouTube',
  1 => 'Funfesty on Twitter: "Je commence à avoir mal à la tête à force',
  2 => 'Sia 2017 Cheap Thrills 2017 live',
)

上述正则表达式模式使用的字符范围从 \x20-\x2122 (spacetrade-mark-sign).我选择这个范围是因为它应该涵盖绝大多数与单词相关的字符,包括带有重音符号的字母和非英语字符。 (不可否认,它还包括许多与单词无关的字符。您可能喜欢使用两个单独的范围以获得更大的特异性,例如:/[^\x{20}-\x{60}\x{7B}-\x{FF}]/ui——这种不区分大小写的搜索两个范围:space重音符号左大括号带有分音符的拉丁文小写字母y)

如果您发现此范围过大或处理时间过长,您可以自行决定合适的字符范围。

例如,您可能喜欢更轻便但不那么大方的 /[^\x20-\x7E]/u(从 space波浪号).但是,如果你将它应用于我上面的任何一个法语 $VideoTitles 那么你将通过删除合法字母来破坏文本。

这里有一个 menu of characters and their unicode numbers 可以帮助您了解上述范围内和超出范围的内容。

*请记住在结束分隔符后包含一个 unicode 标志 u


为了完整起见,我应该说 literal/narrow 删除两个表情符号的解决方案是:

$VideoTitle=preg_replace('/[\x{1F3A7}\x{1F3AC}]/u','',$VideoTitle);  // omit 2 emojis

这些表情符号称为 "clapper board (U+1F3AC)" 和 "headphone (U+1F3A7)"。