我正在尝试在我的php代码中检测表情符号,并防止用户输入。
我现有的代码是:
if(preg_match('/\xEE[\x80-\xBF][\x80-\xBF]|\xEF[\x81-\x83][\x80-\xBF]/', $value) > 0)
{
//warning...
}
但不适用于所有表情符号。有什么想法吗?
if(preg_match('/\xEE[\x80-\xBF][\x80-\xBF]|\xEF[\x81-\x83][\x80-\xBF]/', $value)
你应该使用 u
修饰符以字符为基础处理你的UTF-8字符串,而不是尝试跟踪UTF-8字节序列。
表情符号编码在 U+1F300–U+1F5FF 区块中。然而:
许多日本运营商的“表情符号”集合中的字符实际上映射到现有的Unicode符号,例如纸牌花色、十二生肖和一些箭头。你现在将这些符号视为“表情符号”吗?
仍然有一些系统不使用新标准化的Unicode表情符号代码点,而是使用专用区域中的临时范围。每个运营商都有自己的编码。iOS 4使用了Softbank集。 更多信息。您可能希望阻止整个专用区域。
例如:
function unichr($i) {
return iconv('UCS-4LE', 'UTF-8', pack('V', $i));
}
if (preg_match('/['.
unichr(0x1F300).'-'.unichr(0x1F5FF).
unichr(0xE000).'-'.unichr(0xF8FF).
']/u'), $value) {
...
}
根据维基百科,Unicode 6.0版的核心表情符号集包括722个字符,其中114个字符映射到早期版本的Unicode标准中一个或多个字符的序列,其余608个字符映射到在Unicode 6.0中引入的一个或多个字符的序列。没有专门为表情符号设置的块 - 新符号编码在七个不同的块中(有些是新创建的),并存在一个名为EmojiSources.txt的Unicode数据文件,其中包括与日本供应商的遗留字符集之间的映射。
这里是映射文件。该文件中有722行,每行代表一个表情符号。
由于没有专门为表情符号设置的块,因此似乎这不是一件容易的事情。您需要调整正则表达式以涵盖所有表情符号Unicode。
您可以像这样匹配单个Unicode:
\x{1F30F}
1F30F是一个地球表情符号的Unicode编码。
很抱歉我没有完整的答案,但这应该能帮助你朝着正确的方向前进。
Miscellaneous_Symbols_And_Pictographs
块中分配的代码点。在Perl中,您将使用。 /\p{Assigned}/ && \p{block=Miscellaneous_Symbols_And_Pictographs}/
或者只是
/\P{Cn}/ && /\p{Miscellaneous_Symbols_And_Pictographs}/
你应该将它们组合成一个模式
/(?=\p{Assigned})\p{Miscellaneous_Symbols_And_Pictographs}/
我不记得PHP使用的PCRE库是否提供了所需的Unicode字符属性访问权限。我的记忆是在这个特定领域它相当薄弱。我认为你只有Unicode脚本属性和一般类别。唉。
有时候你只能使用真正的东西。
由于缺乏良好的Unicode支持,您可能需要自己枚举块:
/(?=\P{Cn})[\x{1F300}-\x{1F5FF}]/
对我来说,这看起来像是一个充满魔法数字的维护噩梦。
/[\x{1F300}-\x{1F5FF}]/]
吗? - tchrist<?php
if (preg_match("/[\u{1f300}-\u{1f5ff}\u{e000}-\u{f8ff}]/u", $text)) {
// echo " oh no. Emojis not allowed!";
}
1f300
- 1f5ff
)和bobnice提出的另一个你可能想要阻止的范围。if(iconv('Windows-1250', 'UTF-8', iconv('UTF-8', 'Windows-1250', $value)) != $value)
iconv
的问题。也许我误解了问题。 - tchrist
unichr(0x2190).'-'.unichr(0x27FF)
。 - bobince