java emoj substring_EmojiReader 一个能在字符串中识别出 Emoji 的简单工具

EmojiReader

一个能在字符串中识别出 Emoji 的简单工具

68747470733a2f2f6a69747061636b2e696f2f762f59766573436865756e672f456d6f6a695265616465722e737667

特性

支持 Unicode12 规范,点此查看

基于 EBNF 状态机的 Emoji 判断,比正则表达式更易维护

准确判断含有 Emoji 的字符串长度

准确切割字符串不会断开 Emoji

长度判断

Emoji

String.length

EmojiReader.getTextLength

1

1

🙂

2

1

👱‍♂

5

1

🏳️‍🌈

6

1

👨‍👩‍👦‍👦

11

1

在Java的字符串中,一个 Emoji 由一个或多个 Unicode 码点(CodePoint)组成,一个码点可能由多个字符组成(取决于码点是否大于 0x010000),因此一个 Emoji 可能由数个字符组成。

0b670ff6fc82aec9ae66d11009bae85c.png

很多业务都需要有字数的判断,比如用户昵称不能过长,发言内容有字数限制等等。如果不对 Emoji 进行特殊处理,往往会出现不符合用户预期的情况。

使用 EmojiReader.getTextLength 可以获取到文本的可视符号的长度,一个 Emoji 的长度为1。

String strWithEmoji = “我是一个😃”;

int error = strWithEmoji.length(); //6

int correct = EmojiReader.getTextLength(strWithEmoji); //5

表情切割

当显示文本过长时,通常我们会省略末尾的文本,并加上省略号。

但如果字符串中含有 Emoji ,切割字符串就很可能把 Emoji 切段,变成乱码。比如下面这个字符串:

"我是

🙂

😐

😎

💏"

经过 String.subString(0, 5) 处理后:

"我是

🙂?"

因为多个 Unicode 码点共同组合才能完成一个 Emoji 的展示,通过切割后剩下的 Unicode 码点会表现出无法正常显示的乱码。

使用 EmojiReader.subSequence 可以按照一个 Emoji 长度为1来进行符合视觉预期的裁剪。

EmojiReader.subSequence("我是🙂😐😎💏", 0, 5) == "我是🙂😐😎"

安装

根目录的 build.gradle 添加:

allprojects {

repositories {

...

maven { url 'https://jitpack.io' }

}

}

使用的模块的 build.gradle 中添加:

dependencies {

api 'com.github.YvesCheung:EmojiReader:x.y.z'

}

其中x.y.z 版本替换为 68747470733a2f2f6a69747061636b2e696f2f762f59766573436865756e672f456d6f6a695265616465722e737667

原理

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}

这里简单地解释一下:

Emoji只有三种形式

第一种是国旗类的,由两个国家区域符组成

两个区域符号组成国旗的样例

108393db45f9d19cd2983456c92c93c6.png

第二种是由表情专属的码点加修饰符组成(修饰符可选)

单个码点组成的样例

c37e02a6d106f349ab7c436dcf861b54.png

码点加上修饰符的样例(此例中修饰符为 \uFE0F \20E3)

14ae73acc75c42ab9dd35c8160fd4bc0.png

第三种是由多个第二种表情通过连接符组成

多个(码点 修饰符)相连的样例(连接符为 \u200D)

dd151e909535b8a47281b73bca8fe1f6.png

经典的全家福

fba0940daa78f60c2e534876e7e90d7c.png

通过全家福可以发现,\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.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值