PHP:如何匹配一系列Unicode配对代理表情符号/表情符号? [英] PHP: How to match a range of unicode paired surrogates emoticons/emoji?
问题描述
anubhava's answer about matching ranges of unicode characters将我带到正则表达式,用于清理特定范围的单个码位字符。有了它,我现在可以将所有miscellaneous symbols in this list(包括表情符号)与这个简单的表达式相匹配:
preg_replace('/[x{2600}-x{26FF}]/u', '', $str);
但是,我也希望与此list of paired/double surrogates emoji中的匹配,但作为nhahtdh explained in a comment:
有一个范围从d800
到dfff
来指定UTF-16中的代理,以允许指定更多字符。单个代理项不是UTF-16中的有效字符(必须使用一对才能指定有效字符)。
例如,当我尝试此操作时:
preg_replace('/x{D83D}x{DE00}/u', '', $str);
仅替换paired surrogates on this list的第一个,即:😀
PHP引发此错误:
我尝试了几种不同的组合,包括UTF8 for 😀(
preg_replace()
:编译失败:不允许的Unicode代码点(>= 0xd800 && <= 0xdfff)
'/[x{00F0}x{009F}x{0098}x{0080}]/u'
)中假定的上述代码点的组合,但仍然无法匹配。我还查看了其他PCRE pattern modifiers,但似乎只有u
允许指向UTF8。
我这里是否遗漏了任何"退出"选项?
推荐答案
revo's comment above非常有助于找到解决方案:
如果您的PHP没有提供针对UTF-16的PCRE版本,那么您就不能执行这样的匹配。从的PHP 7.0开始,您可以使用遵循此语法的Unicode代码点
u{XXXX}
,例如preg_replace("~u{1F600}~", '', $str);
(请注意双引号)
由于我使用的是PHP7,echo "u{1F602}";
根据这个PHP RFC page on unicode escape输出😂。这项建议实质上是:
为双引号字符串和heredocs添加了新的转义序列。
u{ codepoint-digits }
其中codepoint-digits
由十六进制数字组成。
这意味着preg_replace
中的匹配字符串(通常用单引号引起来不会影响双引号字符串变量扩展),现在需要一些preg_quote
magic。这是我想出的解决方案:
preg_replace(
// single point unicode list
"/[x{2600}-x{26FF}".
// http://www.fileformat.info/info/unicode/block/miscellaneous_symbols/list.htm
// concatenates with paired surrogates
preg_quote("u{1F600}", '/')."-".preg_quote("u{1F64F}", '/').
// https://www.fileformat.info/info/unicode/block/emoticons/list.htm
"]/u",
'',
$str
);
这里是proof of the above in 3v4l。
编辑:更简单的解决方案
在another comment made by revo中,似乎通过将Unicode字符直接放入regex字符类,可以支持单引号字符串和之前的PHP版本(如4.3.4):
preg_replace('/[☀-⛿😀-🙏]/u','YOINK',$str);
要使用PHP 7's new feature though,您仍然需要双引号:
preg_replace("/[u{2600}-u{26FF}u{1F600}-u{1F64F}]/u",'YOINK',$str);
这篇关于PHP:如何匹配一系列Unicode配对代理表情符号/表情符号?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!