繁体   English   中英

我如何用java中的unicode替换字符串中的每个表情符号?

[英]How can i replace every emoji in a string with their unicode in java?

我有一个这样的字符串:

"\"title\":\"👺TEST title value 😁\",\"text\":\"💖 TEST text value.\"" ...

我想用它们的 unicode 值替换每个表情符号,如下所示:

"\"title\":\"U+1F47ATEST title value U+1F601\",\"text\":\"U+1F496 TEST text value.\"" ...

在网上搜索了很多之后,我找到了一种使用以下代码将一个符号“翻译”为其 unicode 的方法:

String s = "👺";
int emoji = Character.codePointAt(s, 0); 
String unumber = "U+" + Integer.toHexString(emoji).toUpperCase();

但是现在如何更改我的代码以获取字符串中的所有表情符号?

Ps 可以是 \\Uxxxxx 或 U+xxxxx 格式

试试这个解决方案:

String s = "your string with emoji";

StringBuilder sb = new StringBuilder();

for (int i = 0; i < s.length(); i++) {
  if (Character.isSurrogate(s.charAt(i))) {
    Integer res = Character.codePointAt(s, i);
    i++;
    sb.append("U+" + Integer.toHexString(res).toUpperCase());
  } else {
    sb.append(s.charAt(i));
  }
}

//result
System.out.println(sb.toString());

表情符号分散在不同的unicode 块中 例如👺(0x1F47A) 和💖(0x1F496) 来自杂项符号和象形文字,而😁(0x1F601) 来自表情符号

如果要过滤掉符号,则需要决定要使用哪些 unicode 块(或它们的范围)。 例如:

    String s = "\"title\":\"👺TEST title value 😁\",\"text\":\"💖 TEST text value.\"";
    StringBuilder sb = new StringBuilder();
    for (int i = 0, l = s.length() ; i < l ; i++) {
      char ch = s.charAt(i);
      if (Character.isHighSurrogate(ch)) {
        i++;
        char ch2 = s.charAt(i); // Load low surrogate
        int codePoint = Character.toCodePoint(ch, ch2);
        if ((codePoint >= 0x1F300) && (codePoint <= 0x1F64F)) { // Miscellaneous Symbols and Pictographs + Emoticons
          sb.append("U+").append(Integer.toHexString(codePoint).toUpperCase());
        } else { // otherwise just add characters as is
          sb.append(ch);
          sb.append(ch2);
        }
      } else { // if not a surrogate, just add the character
        sb.append(ch);
      }
    }
    String result = sb.toString();
    System.out.println(result); // "title":"U+1F47ATEST title value U+1F601","text":"U+1F496 TEST text value."

要仅获取表情符号,您可以使用例如此列表来缩小条件范围

但是如果你想转义任何代理符号,你可以在代码中去掉codePoint检查

在您的代码中,您不需要指定任何代码点范围,也不需要担心代理。 相反,只需指定您希望字符以 Unicode 转义形式呈现的 Unicode 块。 这是通过使用Character.UnicodeBlock类中的字段声明来实现的。 例如,判断😁(0x1F601) 是否是表情符号:

boolean emoticon = Character.UnicodeBlock.EMOTICONS.equals(Character.UnicodeBlock.of("😁".codePointAt(0)));
System.out.println("Is 😁 an emoticon? " + emoticon); // Prints true.

这是通用代码。 它将处理任何String ,如果它们在指定的 Unicode 代码块中定义,则将单个字符显示为它们的 Unicode 等效项:

package symbolstounicode;

import java.util.List;
import java.util.stream.Collectors;

public class SymbolsToUnicode {

    public static void main(String[] args) {

        Character.UnicodeBlock[] blocksToConvert = new Character.UnicodeBlock[]{
            Character.UnicodeBlock.EMOTICONS, 
            Character.UnicodeBlock.MISCELLANEOUS_SYMBOLS_AND_PICTOGRAPHS};
        String input = "\"title\":\"👺TEST title value 😁\",\"text\":\"💖 TEST text value.\"";
        String output = SymbolsToUnicode.toUnicode(input, blocksToConvert);

        System.out.println("String to convert: " + input);
        System.out.println("Converted string: " + output);
        assert ("\"title\":\"U+1F47ATEST title value U+1F601\",\"text\":\"U+1F496 TEST text value.\"".equals(output));
    }

    // Converts characters in the supplied string found in the specified list of UnicodeBlocks to their Unicode equivalents.
    static String toUnicode(String s, final Character.UnicodeBlock[] blocks) {

        StringBuilder sb = new StringBuilder("");
        List<Integer> cpList = s.codePoints().boxed().collect(Collectors.toList());

        cpList.forEach(cp -> sb.append(SymbolsToUnicode.inCodeBlock(cp, blocks) ? 
                "U+" + Integer.toHexString(cp).toUpperCase() : Character.toString(cp)));
        return sb.toString();
    }

    // Returns true if the supplied code point is within one of the specified UnicodeBlocks.
    static boolean inCodeBlock(final int cp, final Character.UnicodeBlock[] blocksToConvert) {

        for (Character.UnicodeBlock b : blocksToConvert) {
            if (b.equals(Character.UnicodeBlock.of(cp))) {
                return true;
            }
        }
        return false;
    }
}

这是输出,使用 OP 中的测试数据:

run:
String to convert: "title":"👺TEST title value 😁","text":"💖 TEST text value."
Converted string: "title":"U+1F47ATEST title value U+1F601","text":"U+1F496 TEST text value."
BUILD SUCCESSFUL (total time: 0 seconds)

笔记:

  • 我使用字体Segoe UI Symbol作为代码和输出窗口来正确呈现符号。
  • 代码中的基本思想是:
    • 首先,指定要转换的String ,以及需要将哪些字符转换为 Unicode 的 Unicode 代码块。
    • 接下来,使用String.codePoints()String转换为一组代码点,并将它们存储在List
    • 最后,对于每个代码点,确定它是否存在于任何指定的 Unicode 块中,并在必要时对其进行转换。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM