一个能在字符串中识别出 Emoji 的简单工具 (支持JavaScript/Java)
- 支持 Unicode12 规范,点此查看
- 基于 EBNF 状态机的
Emoji
判断,比正则表达式更易维护 - 准确判断含有
Emoji
的字符串长度 - 准确切割字符串不会断开
Emoji
Emoji | String.length | EmojiReader.getTextLength |
---|---|---|
♀ | 1 | 1 |
🙂 | 2 | 1 |
👱♂ | 5 | 1 |
🏳️🌈 | 6 | 1 |
👨👩👦👦 | 11 | 1 |
在字符串中,一个 Emoji
由一个或多个 Unicode 码点(CodePoint)组成,一个码点可能由多个字符组成(取决于码点是否大于 0x010000),因此一个 Emoji
可能由数个字符组成。
很多业务都需要有字数的判断,比如用户昵称不能过长,发言内容有字数限制等等。如果不对 Emoji
进行特殊处理,往往会出现不符合用户预期的情况。
使用 EmojiReader.getTextLength
可以获取到文本的可视符号的长度,一个 Emoji
的长度为1。
//Java
String strWithEmoji = "我是一个😃";
int error = strWithEmoji.length(); //6
int correct = EmojiReader.getTextLength(strWithEmoji); //5
//JavaScript
const strWithEmoji = '我是一个😃';
const error = strWithEmoji.length; //6
const correct = require('emoji-reader').getTextLength(strWithEmoji); //5
当显示文本过长时,通常我们会省略末尾的文本,并加上省略号。
但如果字符串中含有 Emoji
,切割字符串就很可能把 Emoji
切段,变成乱码。比如下面这个字符串:
"我是🙂😐😎💏"
经过 String.subString(0, 5) 处理后:
"我是🙂?"
因为多个 Unicode 码点共同组合才能完成一个 Emoji
的展示,通过切割后剩下的 Unicode 码点会表现出无法正常显示的乱码。
使用 EmojiReader.subSequence
可以按照一个 Emoji
长度为1来进行符合视觉预期的裁剪。
//JavaScript
import EmojiReader from 'emoji-reader'
//Java
import com.yy.mobile.emoji.EmojiReader
EmojiReader.subSequence("我是🙂😐😎💏", 0, 5) == "我是🙂😐😎"
npm install --save emoji-reader
-
根目录的 build.gradle 添加:
allprojects { repositories { ... maven { url 'https://jitpack.io' } } }
-
使用的模块的 build.gradle 中添加:
dependencies { api 'com.github.YvesCheung.EmojiReader:lib-jvm:x.y.z' }
Unicode 规范文档中给出了 Emoji
的语法,是一个EBNF范式的表达:
possible_emoji :=
flag_sequence
| zwj_element (\x{200D} zwj_element)+
flag_sequence :=
\p{RI} \p{RI}
zwj_element :=
\p{Emoji} emoji_modification?
emoji_modification :=
\p{EMod}
| \x{FE0F} \x{20E3}?
| tag_modifier
tag_modifier :=
[\x{E0020}-\x{E007E}]+ \x{E007F}
这里简单地解释一下:
- 两个区域符号组成国旗的样例
- 单个码点组成的样例
- 码点加上修饰符的样例(此例中修饰符为 \uFE0F \20E3)
- 多个(码点 修饰符)相连的样例(连接符为 \u200D)
- 经典的全家福
通过全家福可以发现,\u1F469 和 \u1F466 都是独立的 Emoji
码点,可以表现出一个人像,当他们通过 \u200D 连接符组合后,就可以表现出一个多人像的新 Emoji
。
一个工程师 \u1F477 和一个女性别 \2640 \FE0F 组合起来,就可以表现出一个女工程师的新 Emoji
。
可选的修饰符 \uFE0F \u20E3 等等跟在独立的 Emoji
码点后面,可以起修改表现颜色/表现性别等作用。
通过修饰符和连接符就能把 Emoji
码点组合出千变万化的表情。
Copyright 2019 YvesCheung
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.