Java 21 中对 Emoji 表情支持的改进

1、概览

Java 21 在 java.lang.Character 类中引入了一组新方法,为 Emoji 表情符号提供更好的支持。通过这些方法,我们可以轻松检查某个字符是否是 Emoji 表情符号,并检查 Emoji 表情符号的属性和特征。

本文将带你了解这些新添加的方法,以及与 Java 21 中 Emoji 表情符号处理相关的关键概念。

2、Character API 的更新

Java 21 在 java.lang.Character 类中引入了六个与 Emoji 表情符号处理相关的新方法。所有新方法都是静态的,以代表字符 Unicode 码点的 int 作为参数,并返回 boolean 值。

Unicode 码点是分配给 Unicode 标准中每个字符的唯一数值。它代表不同平台和语言中的特定字符。例如,码点 U+0041 代表字母 A,十六进制形式为 0x0041

现在,让我们来仔细看看这些与 Emoji 表情符号相关的新方法。

2.1、isEmoji()

isEmoji(int codePoint) 方法是新 emoji 方法中最基本的方法。它接收代表字符 Unicode 码点的 int 值,并返回一个 boolean 值,表示该字符是否为 Emoji。

用法如下;

String messageWithEmoji = "Hello Java 21! 😄";
String messageWithoutEmoji = "Hello Java!";

assertTrue(messageWithEmoji.codePoints().anyMatch(Character::isEmoji));
assertFalse(messageWithoutEmoji.codePoints().anyMatch(Character::isEmoji));

2.2、isEmojiPresentation()

isEmojiPresentation(int codePoint) 方法判断一个字符是否应渲染为 Emoji 表情符号。某些字符,如数字(0-9)和货币符号($),可以根据上下文显示为 Emoji 表情符号或文本字符。

示例如下:

String emojiPresentationMessage = "Hello Java 21! 🔥😄";
String nonEmojiPresentationMessage = "Hello Java 21!";

assertTrue(emojiPresentationMessage.codePoints().anyMatch(Character::isEmojiPresentation));
assertFalse(nonEmojiPresentationMessage.codePoints().anyMatch(Character::isEmojiPresentation));

2.3、isEmojiModifier()

isEmojiModifier(int codePoint) 方法用于检查一个字符是否为 Emoji 表情符号修饰符。Emoji 表情符号修饰符是可以修改现有 Emoji 表情符号外观的字符,例如 应用肤色变化

用法如下:

assertTrue(Character.isEmojiModifier(0x1F3FB)); // 浅肤色
assertTrue(Character.isEmojiModifier(0x1F3FD)); // 中性肤色
assertTrue(Character.isEmojiModifier(0x1F3FF)); // 黑皮肤

如上,我们使用 Unicode 码点的十六进制形式,例如 0x1F3FB,而不是实际的 Emoji 字符,因为 Emoji 修饰符通常不会呈现为独立的 Emoji,而且缺乏视觉区别。

2.4、isEmojiModifierBase()

isEmojiModifierBase(int codePoint) 方法确定一个 Emoji 表情符号是否可以被修饰符修饰。该方法有助于识别支持修改的 Emoji 表情符号,因为并非所有 Emoji 表情符号都具有这种能力。

示例如下:

assertTrue(Character.isEmojiModifierBase(Character.codePointAt("👍", 0)));
assertTrue(Character.isEmojiModifierBase(Character.codePointAt("👶", 0)));
    
assertFalse(Character.isEmojiModifierBase(Character.codePointAt("🍕", 0)));

我们看到,竖起大拇指的表情符号 “👍” 和婴儿表情符号 “👶” 都可以被修饰符修饰,可以通过应用肤色变化来改变它们的外观,从而表达多样性。

而披萨表情符号 “🍕” 则不能被修饰,因为它是一个独立的表情符号,代表一个物体,而不是一个可以修改外观的字符或符号。

2.5、isEmojiComponent()

isEmojiComponent(int codePoint) 方法会检查某个字符是否可用作创建新 Emoji 表情符号的组件。这些字符通常与其他字符组合成新的 Emoji 表情符号,而不是作为独立的 Emoji 表情符号出现。

例如,零宽连字(Zero Width Joiner,ZWJ)字符是一个非打印字符,指示渲染系统将相邻字符显示为单个表情符号。通过使用零宽连接器字符(0x200D)将男人表情符号 “👨”(0x1F468)和火箭表情符号 “🚀”(0x1F680)组合在一起,我们可以创建一个新的宇航员表情符号 “👨‍🚀”。我们可以使用 Unicode 码转换网站 来测试这个组合,输入为:0x1F4680x200D0x1F680

肤色字符也是表情符号的组成部分。我们可以将深肤色字符(0x1F3FF)与挥手表情符号 “👋”(0x1F44B)相结合,创建一个深肤色挥手表情符号 “👋🏿”(0x1F44B0x1F3FF)。由于我们是修改现有表情符号的外观,而不是创建一个新的表情符号,因此无需使用 ZWJ 字符来改变肤色。

示例如下:

assertTrue(Character.isEmojiComponent(0x200D)); // 零宽连字
assertTrue(Character.isEmojiComponent(0x1F3FD)); // 中性肤色

2.6、isExtendedPictographic()

isExtendedPictographic(int codePoint) 方法会检查某个字符是否属于象形符号的大类,其中不仅包括传统的表情符号,还包括文本处理系统通常以不同方式呈现的其他符号。

物体、动物和其他图形符号具有扩展象形属性。虽然它们并不总是被视为典型的表情符号,但需要作为表情符号集的一部分进行识别和处理,以确保正确显示。

示例如下:

assertTrue(Character.isExtendedPictographic(Character.codePointAt("☀️", 0)));  // 太阳与光芒
assertTrue(Character.isExtendedPictographic(Character.codePointAt("✔️", 0)));  // 对号

如果将上述两个码点传递给 isEmojiPresentation() 方法,它们都会返回 false。因为它们属于更广泛的扩展象形类别,但没有 Emoji 表情符号呈现属性。

3、正则表达式中的 Emoji 支持

除了新的 Emoji 表情符号方法,Java 21 还在正则表达式中引入了表情符号支持。现在,我们可以使用 \p{IsXXXX} 结构根据 Emoji 属性来匹配字符。

使用正则表达式搜索字符串中的任何表情符号为例:

String messageWithEmoji = "Hello Java 21! 😄";
Matcher isEmojiMatcher = Pattern.compile("\\p{IsEmoji}").matcher(messageWithEmoji);
    
assertTrue(isEmojiMatcher.find());

String messageWithoutEmoji = "Hello Java!";
isEmojiMatcher = Pattern.compile("\\p{IsEmoji}").matcher(messageWithoutEmoji);
    
assertFalse(isEmojiMatcher.find());

同样,也可以在正则表达式中使用其他表情符号结构:

  • IsEmoji_Presentation
  • IsEmoji_Modifier
  • IsEmoji_Modifier_Base
  • IsEmoji_Component
  • IsExtended_Pictographic

需要注意的是,regex 属性构造使用下划线小写格式来引用方法。这与 Character 类中静态方法使用的驼峰格式不同。

这些正则表达式结构为搜索和处理字符串中的表情符号提供了一种简洁而方便的方法。

4、总结

本文通过示例介绍了 Java 21 Character 类中引入的与 Emoji 表情符号相关的新方法,还介绍了正则表达式中新添加的对 Emoji 表情符号支持,可以通过 Pattern 类搜索 Emoji 表情符号字符及其属性。

当我们构建聊天应用、社交媒体平台或任何其他类型的使用 Emoji 表情符号的应用时,这些新功能都会对我们有所帮助。


Ref:https://www.baeldung.com/java-21-improved-emoji-support