主页C++ Builder 资料C++ Builder 参考手册System 字符串GetUnicodeCategory
C++ Builder 串口控件
C++ Builder 编程技巧
C++ Builder 操作指南
C++ Builder 参考手册
基础知识
cfloat 浮点数
cmath 数学函数
cstdlib 标准库函数
System 字符串
 • UnicodeString
 • UTF8String
 • TStringList
 • TStrings
 • String
 • AnsiString
 • AnsiStringBase
 • AnsiStringT
 • RawByteString
 • UCS4String
 • WideString
 • EnumToStr
 • FloatToStr
 • FloatToStrF
 • FormatFloat
 • IntToStr
 • UIntToStr
 • IntToHex
 • StrToEnum
 • StrToFloat
 • StrToFloatDef
 • StrToInt
 • StrToIntDef
 • StrToInt64
 • StrToInt64Def
 • StrToUInt64
 • StrToUInt64Def
 • TFloatFormat
 • GetUnicodeCategory
 • IMLangCodePages
 • StringReplace
System 日期和时间
System.Math.hpp 数学函数
其他数据类型
VCL 基础类
VCL 应用程序
Pictures 图片
Graphics 绘图
Additional 控件
System 控件
A ~ Z 字母顺序排列的目录
网友留言/技术支持
GetUnicodeCategory - 获取字符类型

函数原型:

TUnicodeCategory __fastcall GetUnicodeCategory(System::WideChar C);
TUnicodeCategory __fastcall GetUnicodeCategory(System::UCS4Char C);
TUnicodeCategory __fastcall GetUnicodeCategory(const System::UnicodeString S, int Index);

头文件:

#include <System.Character.hpp> (XE2 之后) #include <Character.hpp> (XE 之前)

参数:

C: 单个字符;
S: 字符串,index: 在字符串里面的字符序号,获取字符串 S 里面的第 index 个字符的类型。

注:如果获取单个字符的类型,可能会返回 ucSurrogate 代理对类型,
    如果获取字符串里面的字符,不会返回 ucSurrogate 代理对这个类型,而是计算出代理对的 UNICODE 编码值,然后返回这个 UNICODE 字符的真实类型。

返回值:

TUnicodeCategory 枚举类型,可以是以下表格里面的值:

字符类型 描述 示例
ucControl 控制符 回车换行 "\r\n"
ucFormat 格式符 U+202B Right-To-Left Embedding [RLE]
ucUnassigned 未定义的。这个函数遗漏的,或者是新版本 UNICODE 新增的文字或符号 汉字 鿌鿍鿎鿏鿐鿑鿒鿓鿔鿕,字母 Ԭԯԧ,表情符号 😀😁😂😃😄,其他符号 ✅✨⮂⏰ 等
ucPrivateUse 专用区
可以存放自定义字符的区域
平面 15 和平面 16 上各有 65534 个码位,
分别是 0xF0000 ~ 0xFFFFD 和 0x100000 ~ 0x10FFFD
ucSurrogate 代理对字符
包括前导代理后尾代理
基本多语言平面 (BMP) 里面的 U+D800 ~ U+DFFF 这段码位,
只有获取单个字符的时候会出现这个值,
如果对字符串进行解析,会解析到代理对表示的实际字符的类型
ucLowercaseLetter 小写字母 abcωπāáǎà 等
ucModifierLetter 修饰字母 ˇˆʾʿ 等
ucOtherLetter 不区分大小写的字母 汉字、阿拉伯文、朝鲜语、日语等
ucTitlecaseLetter 用于标题的大小写状态的字母 拉丁字母 DžLjNjDz 和希腊字母 ᾈᾏᾘᾟᾨᾯ 等
ucUppercaseLetter 大写字母 ABCΩΠĀÁǍÀ 等
ucCombiningMark 组合字符,很多组合字符会识别分类为ucEnclosingMark 和 ucNonSpacingMark ःािी 等
ucEnclosingMark 组合字符,没找到相关的说明,
测试结果:这些字符会和其他字符重叠在一起
字符 ҈ 插入在 “abc123汉字” 的每个字符之间:“a҈b҈c҈1҈2҈3҈汉҈字
字符 ꙲ 插入在 “abc123汉字” 的每个字符之间:“a꙲b꙲c꙲1꙲2꙲3꙲汉꙲字
ucNonSpacingMark 组合字符,没有间距的标记 â 看上去是一个字符,其实是两个字符 a 和 ̂ ,他们挨在一起就组合在一起了。“̂ ” 就是没有间距的标记 (组合字符)
ucDecimalNumber 十进制数 通用阿拉伯数字 0123456789,阿拉伯文数字 ٠١٢٣٤٥٦٧٨٩ 等
ucLetterNumber 字母数字 罗马数字 ⅠⅡⅢⅣⅤⅥⅦⅧⅨⅩⅪⅫ 和 ⅰⅱⅲⅳⅴⅵⅶⅷⅸⅹⅺⅻ 等
ucOtherNumber 其他数字 ½¼¾ ¹²³ ₁₂₃ ①②③ ⑴⑵⑶ ❶❷❸ ㊀㊁㊂ 等
ucConnectPunctuation 连接标点符号 _‿⁀⁔︳︴﹍﹎﹏_ 等
ucDashPunctuation 划线标点符号 -֊־᐀᠆‐‑‒–—―⸗⸚〜〰゠︱︲﹘﹣- 等
ucClosePunctuation 结束标点符号 (括号) )]}〉》」』】〗﹀︾﹂﹄︼︘ 等
ucFinalPunctuation 结束标点符号 (引号) »’” 等
ucInitialPunctuation 开始标点符号 (引号) «‘“ 等
ucOtherPunctuation 其他标点符号 (不区分开始与结束的) !"'#%&*?,。 等
ucOpenPunctuation 开始标点符号 (括号) ([{〈《「『【〖︿︽﹁﹃︻︗ 等
ucCurrencySymbol 货币符号 $¢£¤¥₤€ 等
ucModifierSymbol 修饰符号 ^`¨¯´ 等
ucMathSymbol 数学符号 +<=>|~¬±×÷϶∀∂∃∄∅∆∇∈∉∏∑∘∝∞∟∠∡∢∩∪∫∬∭∮∯∰∴∵≈≉≌ 等
ucOtherSymbol 其他符号 ©®°¶℗℡™℻⌂⌨☑☐☒☮☯♪⚽⚾✓✗ 等
ucLineSeparator 行分割符 U+2028 LINE SEPARATOR
ucParagraphSeparator 段落分割符 U+2029 PARAGRAPH SEPARATOR
ucSpaceSeparator 空格 中文排版经常用到的:
U+0020 SPACE [SP] 普通的空格,英文空格
U+3000 IDEOGRAPHIC SPACE 中文全角空格
还有其他的不同宽度或功能空格,
例如 U+00A0 NO-BREAK SPACE [NBSP] 不间断的空格和 U+2000 ~ U+200A 等

 

例:获取字符串长度、字符个数、每个字符的类型

#include <System.Character.hpp> // XE 之前为 #include <Character.hpp>
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
  UnicodeString sText = L"Ab€δ汉字螭𧉚𧈢𧏡123😊☯"; // 螭𧉚和𧈢𧏡常误写为螭吻和蚣蝮
  int iLength = sText.Length();
  int iCharCount = 0;
  Memo1->Lines->Add(L"字符串长度:" + IntToStr(iLength) + L" (个 wchar_t)");
  for(int i=1; i<=iLength; i++)
   {
     UnicodeString::TStringLeadCharType ct = sText.ByteType(i);
     UnicodeString sInfo = L"第 "+ IntToStr(i) +L" 个 wchar_t: "+ EnumToStr(ct);

     switch(ct)
      {
        case UnicodeString::ctNotLeadChar   :
         {
           iCharCount++;
           TUnicodeCategory uc = GetUnicodeCategory(sText, i);
           sInfo += L", 第 " + IntToStr(iCharCount) + L" 个字符";
           sInfo += L", 单独字符: \"" + sText.SubString(i,1);
           sInfo += L"\", " + EnumToStr(uc);
         } break;
        case UnicodeString::ctbLeadSurrogate:
         {
           iCharCount++;
           TUnicodeCategory uc = GetUnicodeCategory(sText, i);
           sInfo += L", 第 " + IntToStr(iCharCount) + L" 个字符";
           sInfo += L", 与后组为: \"" + sText.SubString(i,2);
           sInfo += L"\", " + EnumToStr(uc);
         } break;
        case UnicodeString::ctTrailSurrogate:
         {
           sInfo += L", 与前组合";
         } break;
      }
     Memo1->Lines->Add(sInfo);
   }
  Memo1->Lines->Add(L"一共 " + IntToStr(iCharCount) + L"个字符");
}

执行结果分析:
(1) 字符串长度 19,一共 15 个字符,“𧉚𧈢𧏡” 这三个汉字和 “😊” 这个表情符号是代理对,即 2 个 char16_t 组合成的 4 字节的字符,是在 UNICODE 辅助平面里面的字符,其他的字符都是单个 char16_t 的。

由于很多软件和网站代码都不支持代理对,或者无法正确处理代理对,所以无法支持 UNICODE 辅助平面里面的字符,螭𧉚和𧈢𧏡常误写为螭吻和蚣蝮就很容易理解了,由于软件不支持,就用了相近的字代替,这让电脑里面的文章出现很多的错别字。由于辅助平面里面的文字几乎都是不常用的文字,所以多数软件厂家也并不关心代理对和辅助平面。

由于在 UNICODE 6.0 版本开始增加了表情符号 Emoticons/Emoji,例如 “😊”,这些表情符号在辅助平面里面,这反而让很多软件厂家感兴趣,让很多软件支持了代理对和辅助平面字符,所以我们还是应该感谢一下 Emoticons 让很多软件支持了 UNICODE 辅助平面里面不常用的文字。

(2) C++ Builder 里面的 GetUnicodeCategory 函数可以区分不同语言的文字当中的符号,大小写等,例如 “A” 是大写字母,“δ” 是小写字母,“€” 是货币符号,汉字是不区分大小写的字母,BMP 和辅助平面里面的汉字都可以识别,“☯” 是其他符号,而表情符号 “😊” 识别为 ucUnassigned 未定义的分类,这说明,在这个测试程序使用的 C++ Builder 10.1 Berlin 版本,还不支持把表情符号识别为一个字符分类。

◤上一页:TFloatFormat下一页:IMLangCodePages

C++ 爱好者 -- Victor Chen 的个人网站 www.cppfans.com 辽ICP备11016859号