c++ - 如何测试字符串是否包含表情符号?

标签 c++ icu

我正在使用 ICU4C 并尝试在 UTF-8 字符串中查找表情符号簇。这是迄今为止我得到的最接近的结果,但它错误地将简单字符“#”限定为表情符号(因为“#️⃣”以“#”开头,并且“可能”是一个表情符号,因此“#”确实带有属性 UCHAR_EMOJI)。

我认为最好的办法是尝试获取属性RGI_Emoji,如here所示。但这是一个“字符串”属性,而不是“代码点”属性,我不知道该怎么做。如果可以的话,我会将每个字符分析为“字符串”并测试该字符串属性。文档指出,目前,使用正则表达式无法获取“字符串”属性。

const std::string s8 = "#🤙🏿asd🧔🏼😵‍💫dds🫥😶‍🌫️🏌️‍♂️🇨🇦ds#️⃣🏋🏽ds👨‍👩‍👦‍👦ds👩🏾‍❤️‍💋‍👨🏼ds";
const icu::UnicodeString us = icu::UnicodeString::fromUTF8(s8);
UErrorCode status = U_ZERO_ERROR;
icu::BreakIterator* bi = icu::BreakIterator::createCharacterInstance(icu::Locale::getUS(), status);
bi->setText(us);
bool is_emoji = false;
for(int32_t e = bi->first(), b = e; e != icu::BreakIterator::DONE; b = e, e = bi->next())
{
    // Analyze character for emoji-ness.
    for(int32_t i = b; i != e; ++i)
    {
        std::cout << us.char32At(i) << ' ';
        is_emoji = u_hasBinaryProperty(us.char32At(i), UProperty::UCHAR_EMOJI) || u_hasBinaryProperty(us.char32At(i), UProperty::UCHAR_EMOJI_COMPONENT);
    }
    if(is_emoji)
    {
        std::cout << "<- is emoji\n";
        ++emojis;
        is_emoji = false;
    }
    else
    {
        std::cout << "<- is not emoji\n";
    }
    ++characters;

}
delete bi;

最佳答案

看起来像u_stringHasBinaryProperty将使您能够访问 UCHAR_RGI_EMOJI。请注意,此方法在 ICU 版本 < 70 中不可用。

我认为您需要区分由单个代码点组成的基本表情符号(例如 U+1F600 😀)和表情符号序列(例如 U+0023 U+FE0F U+20E3 #️⃣)。 basic emoji将同时设置 UCHAR_EMOJIUCHAR_BASIC_EMOJI 属性,并取消设置 UCHAR_EMOJI_COMPONENTfirst code point in a sequence将设置 UCHAR_EMOJIUCHAR_EMOJI_COMPONENT,但不设置 UCHAR_BASICSubsequent code points将设置 UCHAR_EMOJI_COMPONENT,但不会设置 UCHAR_EMOJI(也不会设置 UCHAR_BASIC_EMOJI)。

如果遇到“#”(基本上是设置了 UCHAR_EMOJIUCHAR_EMOJI_COMPONENT 的任何代码点),则需要检查下一个代码点。仅当下一个代码点没有 UCHAR_EMOJI 但有 UCHAR_EMOJI_COMPONENT 时,“#”才是表情符号的一部分。

关于c++ - 如何测试字符串是否包含表情符号?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73634556/

相关文章:

java - 如何使用 ICU4J 库

node.js - libicui18n.so.52 : cannot open shared object file

c++ - std::map 设计:使用 std::string 作为映射键和存储的对象名称(成员)

c++ - 将二维 QVariantList 从 C++ 传递到 QML

c++ - 临时局部变量的命名约定

c++ - typename参数包和auto参数包的区别?

c++ - 将 cmake 项目与 Qt5 链接时部署 icu 库

c++ - NumberFormat/DecimalFormat 将某些浮点值视为 long 而不是 double

android - 使用 arm-linux-androideabi-4.4.3 编译 ICU

c++ - 如何用 "-pthread"而不是 "-mthread"编译 boost_thread?