PHP:如何匹配一系列 unicode 配对代理表情符号/表情符号?
Posted
技术标签:
【中文标题】PHP:如何匹配一系列 unicode 配对代理表情符号/表情符号?【英文标题】:PHP: How to match a range of unicode paired surrogates emoticons/emoji? 【发布时间】:2019-01-27 13:28:55 【问题描述】:anubhava's answer about matching ranges of unicode characters 引导我使用正则表达式来清理特定范围的单个字符代码点。有了它,现在我可以用这个简单的表达式匹配所有miscellaneous symbols in this list(包括表情符号):
preg_replace('/[\x2600-\x26FF]/u', '', $str);
但是,我也想匹配这个list of paired/double surrogates emoji中的那些,但是作为nhahtdh explained in a comment:
在
d800
到dfff
的范围内可以指定UTF-16 中的代理项以允许指定更多字符。 单个代理不是 UTF-16 中的有效字符(需要一对来指定有效字符)。
所以,例如,当我尝试这个时:
preg_replace('/\xD83D\xDE00/u', '', $str);
仅替换paired surrogates on this list 中的第一个,即:????
php 抛出这个:
preg_replace()
:编译失败:不允许的 Unicode 代码点(>= 0xd800 && <= 0xdfff)
我尝试了几种不同的组合,包括UTF8 for ???? ('/[\x00F0\x009F\x0098\x0080]/u'
) 中上述代码点的假定组合,但我仍然无法匹配它。我还查看了其他PCRE pattern modifiers,但似乎u
是唯一允许指向UTF8 的。
我在这里错过了任何“逃避”的选择吗?
【问题讨论】:
您是否只是想构建一个正则表达式来匹配这 80 个表情符号并将其用作“硬编码”模式,或者您是否正在尝试编写将“转换”U+1F600
到 \xD83D\xDE00
的代码?
哪个 PHP 版本?
@WiktorStribiżew 如果可能的话。 hardcoded 模式将是一个范围。
@revo PHP 7.1.5 及以上版本。
如果您的 PHP 未附带针对 UTF-16 的 PCRE 构建,那么您将无法执行此类匹配。从 PHP 7.0 开始,您可以使用 Unicode 代码点,遵循此语法 \uXXXX
,例如preg_replace("~\u1F600~", '', $str);
(注意双引号)
【参考方案1】:
revo's comment above 对找到解决方案很有帮助:
如果您的 PHP 未附带针对 UTF-16 的 PCRE 构建,则您无法执行此类匹配。 从 PHP 7.0 开始,您可以使用 Unicode 代码点遵循此语法
\uXXXX
例如preg_replace("~\u1F600~", '', $str);
(注意双引号)
由于我使用的是 PHP 7,echo "\u1F602";
输出?根据这个PHP RFC page on unicode escape。这个提议本质上是:
为 双引号字符串 和 heredocs 添加了新的转义序列。
\u codepoint-digits
其中codepoint-digits
由十六进制数字组成。
这意味着preg_replace
中的匹配字符串(通常是单引号以免与双引号字符串变量扩展混淆)现在需要一些preg_quote
magic。这是我想出的解决方案:
preg_replace(
// single point unicode list
"/[\x2600-\x26FF".
// http://www.fileformat.info/info/unicode/block/miscellaneous_symbols/list.htm
// concatenates with paired surrogates
preg_quote("\u1F600", '/')."-".preg_quote("\u1F64F", '/').
// https://www.fileformat.info/info/unicode/block/emoticons/list.htm
"]/u",
'',
$str
);
这是proof of the above in 3v4l。
编辑:更简单的解决方案
在another comment made by revo 中,似乎通过将 unicode 字符直接放入正则表达式字符类,支持单引号字符串和以前的 PHP 版本(例如 4.3.4):
preg_replace('/[☀-⛿?-?]/u','YOINK',$str);
对于使用PHP 7's new feature though,你仍然需要双引号:
preg_replace("/[\u2600-\u26FF\u1F600-\u1F64F]/u",'YOINK',$str);
这里是revo's proof in 3v4l。
【讨论】:
我想补充一点,您既不需要preg_quote
也不需要 PCRE 的 \xXXXX
语法。只需使用/[\u2600-\u26FF\u1F600-\u1F64F]/u
。这等于/[☀-⛿?-?]/u
。在此处查看现场演示3v4l.org/uA3mD
@revo 哈哈,这太棒了!直接放置字符允许在 PHP 4 中替换!我想这是最好的解决方案(如果 IDE 没有崩溃的话)。我用你的发现编辑了答案。非常感谢!以上是关于PHP:如何匹配一系列 unicode 配对代理表情符号/表情符号?的主要内容,如果未能解决你的问题,请参考以下文章