You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在不依赖ICU库的C++中判断字符是否属P类Unicode范畴?

实现Python风格的Unicode标点判断(无额外编译依赖)

你需要在C++中实现与Python unicodedata.category(char).startswith("P") 等价的逻辑,且不依赖ICU这类需要编译的库,以下是几种可行方案:

方案一:利用C++标准库宽字符函数

C++标准库的<cwctype>提供了iswpunct函数,可判断宽字符是否为标点。结合UTF-8转码和正确的区域设置,可覆盖大部分Unicode标点场景。

代码示例

#include <cwctype>
#include <locale>
#include <codecvt>
#include <string>
#include <cstdint>

// 将UTF-8字符串转换为UTF-32(处理任意Unicode字符)
std::u32string utf8_to_utf32(const std::string& utf8_str) {
    std::wstring_convert<std::codecvt_utf8<char32_t>, char32_t> converter;
    return converter.from_bytes(utf8_str);
}

// 判断单个Unicode字符是否为标点
bool is_unicode_punct(char32_t c) {
    // 假设平台wchar_t为32位(如Linux、macOS),若为16位需额外处理
    wchar_t wc = static_cast<wchar_t>(c);
    return iswpunct(wc) != 0;
}

int main() {
    // 设置支持UTF-8的区域设置
    std::setlocale(LC_ALL, "en_US.UTF-8");
    
    std::string test = "Hello! 世界,。";
    auto utf32 = utf8_to_utf32(test);
    for (char32_t c : utf32) {
        // 输出判断结果(仅示例,实际可按需处理)
        printf("U+%04X: %s\n", static_cast<uint32_t>(c), is_unicode_punct(c) ? "是标点" : "非标点");
    }
    return 0;
}

注意:std::wstring_convert在C20中被弃用,若使用C20及以上版本,可替换为仅头文件的UTF-8转码库(如utf8cpp)。另外,iswpunct的判断规则与Python的标点类别存在细微差异,若需严格对齐,建议使用方案二。

方案二:手动匹配Unicode标点范围

直接根据Unicode标准中P类标点的字符范围进行判断,完全不依赖外部库,且与Python逻辑严格一致。

代码示例

#include <vector>
#include <algorithm>
#include <cstdint>

// 存储Unicode字符区间的结构体
struct CharRange {
    char32_t start;
    char32_t end;
};

// 整理自Unicode标准的P类标点全范围(含Pc、Pd、Ps、Pe、Pi、Pf、Po子类)
const std::vector<CharRange> PUNCTUATION_RANGES = {
    // Pc 连接标点
    {0x005F, 0x005F}, {0x203F, 0x2040}, {0x2054, 0x2054}, {0xFE33, 0xFE34}, {0xFE4D, 0xFE4F}, {0xFF3F, 0xFF3F},
    // Pd Dash标点
    {0x002D, 0x002D}, {0x058A, 0x058B}, {0x1400, 0x1400}, {0x1806, 0x1806}, {0x2010, 0x2015}, {0x2E17, 0x2E17}, {0x2E1A, 0x2E1A}, {0x2E3A, 0x2E3B}, {0x2E40, 0x2E40}, {0x301C, 0x301C}, {0x3030, 0x3030}, {0x30A0, 0x30A0}, {0xFE31, 0xFE32}, {0xFE58, 0xFE58}, {0xFF0D, 0xFF0D},
    // Ps 开始标点
    {0x0028, 0x0029}, {0x005B, 0x005D}, {0x007B, 0x007D}, {0x0F3A, 0x0F3B}, {0x0F3D, 0x0F3E}, {0x169B, 0x169C}, {0x2018, 0x2018}, {0x201C, 0x201C}, {0x2039, 0x2039}, {0x2045, 0x2046}, {0x207D, 0x207E}, {0x208D, 0x208E}, {0x2329, 0x2329}, {0x2768, 0x276B}, {0x276D, 0x276E}, {0x2770, 0x2773}, {0x2775, 0x2776}, {0x2E22, 0x2E23}, {0x2E25, 0x2E26}, {0x2E28, 0x2E29}, {0x3008, 0x300B}, {0x300E, 0x3011}, {0x3014, 0x3017}, {0xFE35, 0xFE36}, {0xFE39, 0xFE3A}, {0xFE3C, 0xFE3D}, {0xFE41, 0xFE42}, {0xFE47, 0xFE48}, {0xFF08, 0xFF09}, {0xFF3B, 0xFF3D}, {0xFF5B, 0xFF5D},
    // Pe 结束标点
    {0x0029, 0x0029}, {0x005D, 0x005D}, {0x007D, 0x007D}, {0x0F3B, 0x0F3B}, {0x0F3E, 0x0F3E}, {0x169C, 0x169C}, {0x2019, 0x2019}, {0x201D, 0x201D}, {0x203A, 0x203A}, {0x2046, 0x2046}, {0x207E, 0x207E}, {0x208E, 0x208E}, {0x232A, 0x232A}, {0x2769, 0x276C}, {0x276F, 0x2770}, {0x2774, 0x2774}, {0x2777, 0x2778}, {0x2E24, 0x2E24}, {0x2E27, 0x2E27}, {0x2E2A, 0x2E2A}, {0x3009, 0x300C}, {0x3010, 0x3013}, {0x3018, 0x301B}, {0xFE36, 0xFE37}, {0xFE3A, 0xFE3B}, {0xFE3E, 0xFE3F}, {0xFE43, 0xFE44}, {0xFE49, 0xFE4A}, {0xFF09, 0xFF09}, {0xFF3D, 0xFF3D}, {0xFF5D, 0xFF5D},
    // Pi 初始引号
    {0x2018, 0x2018}, {0x201C, 0x201C}, {0x2039, 0x2039}, {0x300E, 0x300E}, {0x3014, 0x3014}, {0xFE41, 0xFE41}, {0xFE47, 0xFE47}, {0xFF08, 0xFF08}, {0xFF3B, 0xFF3B},
    // Pf 最终引号
    {0x2019, 0x2019}, {0x201D, 0x201D}, {0x203A, 0x203A}, {0x300F, 0x300F}, {0x3015, 0x3015}, {0xFE42, 0xFE42}, {0xFE48, 0xFE48}, {0xFF09, 0xFF09}, {0xFF3D, 0xFF3D},
    // Po 其他标点
    {0x0021, 0x0023}, {0x0025, 0x002A}, {0x002C, 0x002F}, {0x003A, 0x003B}, {0x003F, 0x0040}, {0x005B, 0x005D}, {0x005F, 0x005F}, {0x007B, 0x007E}, {0x00A1, 0x00A1}, {0x00AB, 0x00AB}, {0x00B7, 0x00B7}, {0x00BB, 0x00BB}, {0x00BF, 0x00BF}, {0x037E, 0x037E}, {0x0387, 0x0387}, {0x055A, 0x055F}, {0x0589, 0x058A}, {0x05BE, 0x05BE}, {0x05C0, 0x05C0}, {0x05C3, 0x05C3}, {0x05F3, 0x05F4}, {0x060C, 0x060C}, {0x060D, 0x060D}, {0x061B, 0x061B}, {0x061E, 0x061F}, {0x066A, 0x066D}, {0x06D4, 0x06D4}, {0x0700, 0x070D}, {0x07F7, 0x07F9}, {0x0830, 0x083E}, {0x085E, 0x085E}, {0x0964, 0x0965}, {0x0970, 0x0970}, {0x0DF4, 0x0DF4}, {0x0E4F, 0x0E5B}, {0x0F04, 0x0F12}, {0x0F14, 0x0F14}, {0x0F3A, 0x0F3A}, {0x0F3C, 0x0F3C}, {0x0F3E, 0x0F3E}, {0x0F85, 0x0F85}, {0x0FBE, 0x0FC5}, {0x0FC7, 0x0FCC}, {0x0FD0, 0x0FD4}, {0x0FD9, 0x0FDA}, {0x104A, 0x104F}, {0x10FB, 0x10FB}, {0x1360, 0x1368}, {0x1400, 0x1400}, {0x166D, 0x166E}, {0x16EB, 0x16ED}, {0x1735, 0x1736}, {0x17D4, 0x17D6}, {0x17D8, 0x17DA}, {0x1800, 0x180A}, {0x1944, 0x1945}, {0x19DE, 0x19DF}, {0x1A1E, 0x1A1F}, {0x1AA0, 0x1AA6}, {0x1AA8, 0x1AAD}, {0x1B5A, 0x1B60}, {0x1BFC, 0x1BFF}, {0x1C3B, 0x1C3F}, {0x1C7E, 0x1C7F}, {0x1CC0, 0x1CC7}, {0x1CD3, 0x1CD3}, {0x2010, 0x2010}, {0x2012, 0x2013}, {0x2015, 0x2015}, {0x2017, 0x2017}, {0x2020, 0x2027}, {0x2030, 0x2038}, {0x203B, 0x2043}, {0x2045, 0x2046}, {0x2048, 0x2051}, {0x2053, 0x205E}, {0x207D, 0x207E}, {0x208D, 0x208E}, {0x2329, 0x232A}, {0x2768, 0x2775}, {0x2794, 0x2797}, {0x2B1B, 0x2B1C}, {0x2B50, 0x2B50}, {0x2B55, 0x2B55}, {0x2E00, 0x2E2E}, {0x2E30, 0x2E4F}, {0x3001, 0x3003}, {0x3008, 0x3011}, {0x3014, 0x301F}, {0x3030, 0x3030}, {0x303D, 0x303D}, {0x30A0, 0x30A0}, {0x30FB, 0x30FB}, {0xA4FE, 0xA4FF}, {0xA60D, 0xA60F}, {0xA673, 0xA673}, {0xA67E, 0xA67F}, {0xA6F2, 0xA6F7}, {0xA874, 0xA877}, {0xA8CE, 0xA8CF}, {0xA8F8, 0xA8F9}, {0xA8FF, 0xA8FF}, {0xA92E, 0xA92F}, {0xA95F, 0xA95F}, {0xA9C1, 0xA9C1}, {0xA9E5, 0xA9E6}, {0xAA5C, 0xAA5F}, {0xAADE, 0xAADF}, {0xAAF0, 0xAAF1}, {0xABEB, 0xABEB}, {0xFDFC, 0xFDFC}, {0xFE10, 0xFE19}, {0xFE30, 0xFE4F}, {0xFE50, 0xFE6B}, {0xFE6C, 0xFE6C}, {0xFE6E, 0xFE6F}, {0xFF01, 0xFF03}, {0xFF05, 0xFF0A}, {0xFF0C, 0xFF0F}, {0xFF1A, 0xFF1B}, {0xFF1F, 0xFF20}, {0xFF3B, 0xFF3D}, {0xFF3F, 0xFF3F}, {0xFF5B, 
相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 23:43:55