检测字符串中的字符是否是表情符号(使用Android)
就像标题所说。 我想知道给定的java String是否包含表情符号。
我不能使用Character.UnicodeBlock.of(char) == Character.UnicodeBlock.EMOTICONS
因为这需要API级别19。
我发现这个代码适用于iOS但它并不适用,因为它看起来像java和objective-c以不同的方式处理代理对。
我看过的文件告诉我:
A char value, therefore, represents Basic Multilingual Plane (BMP) code points, including the surrogate code points, or code units of the UTF-16 encoding
我不太清楚这意味着什么。 这仅仅意味着他们还将BMP点作为他们的第一个数字吗?
根据维基百科 ,表情符号集位于0x1f600和0x1f64f之间,但我不知道如何检查char是否在该范围内。
我曾希望这样的东西能起作用,但事实并非如此
if (0x1f600 <= a && a <= 0x1f64f) { Print.d("Unicode", "groovy!"); }
那么我该怎么做呢?
我实际上能够使用链接的iOS代码来创建以下function。 我没有意识到包含例如单个表情符号的字符串将具有2的长度。因此,您可以检查字符是否实际上是代理。
我不完全确定如何从iOS代码中处理else if (substring.length > 1)
,但我认为Character.isHighSurrogate(myChar)
在该实例中执行相同的工作。
private boolean containsIllegalCharacters(String displayName) { final int nameLength = displayName.length(); for (int i = 0; i < nameLength; i++) { final char hs = displayName.charAt(i); if (0xd800 <= hs && hs <= 0xdbff) { final char ls = displayName.charAt(i + 1); final int uc = ((hs - 0xd800) * 0x400) + (ls - 0xdc00) + 0x10000; if (0x1d000 <= uc && uc <= 0x1f77f) { return true; } } else if (Character.isHighSurrogate(hs)) { final char ls = displayName.charAt(i + 1); if (ls == 0x20e3) { return true; } } else { // non surrogate if (0x2100 <= hs && hs <= 0x27ff) { return true; } else if (0x2B05 <= hs && hs <= 0x2b07) { return true; } else if (0x2934 <= hs && hs <= 0x2935) { return true; } else if (0x3297 <= hs && hs <= 0x3299) { return true; } else if (hs == 0xa9 || hs == 0xae || hs == 0x303d || hs == 0x3030 || hs == 0x2b55 || hs == 0x2b1c || hs == 0x2b1b || hs == 0x2b50) { return true; } } } return false; }
四年后……
此时,利用EmojiCompat
可能更有意义。 此代码假设您在应用启动时初始化了EmojiCompat
。 这里的基本思想是让EmojiCompat
处理你的CharSequence
,在任何表情符号出现的任何地方插入EmojiSpan
实例,然后检查结果。
public static boolean containsEmoji(CharSequence charSequence) { boolean result = false; CharSequence processed = EmojiCompat.get().process(charSequence, 0, charSequence.length() -1, Integer.MAX_VALUE, EmojiCompat.REPLACE_STRATEGY_ALL); if (processed instanceof Spannable) { Spannable spannable = (Spannable) processed; result = spannable.getSpans(0, spannable.length() - 1, EmojiSpan.class).length > 0; } return result; }
如果要收集给定CharSequence
中出现的唯一表情符号列表,可以执行以下操作,迭代getSpans()
的结果并查找每个跨度的开始和结束以捕获EmojiCompat
发现的表情符号:
@NonNull public static List getUniqueEmoji(CharSequence charSequence) { Set emojiList = new HashSet<>(); CharSequence processed = EmojiCompat.get().process(charSequence, 0, charSequence.length() -1, Integer.MAX_VALUE, EmojiCompat.REPLACE_STRATEGY_ALL); if (processed instanceof Spannable) { Spannable spannable = (Spannable) processed; EmojiSpan[] emojiSpans = spannable.getSpans(0, spannable.length() - 1, EmojiSpan.class); for (EmojiSpan emojiSpan : emojiSpans) { int spanStart = spannable.getSpanStart(emojiSpan); int spanEnd = spannable.getSpanEnd(emojiSpan); CharSequence emojiCharSequence = spannable.subSequence(spanStart, spanEnd); emojiList.add(String.valueOf(emojiCharSequence)); } } return emojiList.size() > 0 ? new ArrayList<>(emojiList) : new ArrayList (); }
尝试这个…
if (Integer.parseInt("1f600", 16) <= (int)'☺' && (int)'☺' <= Integer.parseInt("1f64f", 16)) { Print.d("Unicode", "groovy!"); }
这可能有效,因为hex值和char值都被转换为int。