)
示例工程【免费下载链接】Windows-universal-samplesAPI samples for the Universal Windows Platform.项目地址https://gitcode.com/gh_mirrors/wi/Windows-universal-samples点击查看免费下载本指南围绕 Samples/Unicode/README.md 展开讲解 UWPWindows 通用应用平台下如何借助Windows.Data.Text.UnicodeCharacters类处理字符串中的 Unicode 属性核心实战场景是从一段自然语言文本中提取词法标识符lexical identifiers并正确处理位于增补平面supplementary plane的字符。读完本文你将掌握IsIdStart/IsIdContinue/IsHighSurrogate/IsLowSurrogate/GetCodepointFromSurrogatePair这组 API 的用法、代理对合并的完整算法以及同一场景在 C# 与 C/WinRT 两种语言下的对应实现。示例概览Unicode 字符串处理样例要解决什么问题Windows 的文本输入、搜索、代码编辑器、语法高亮等场景都依赖把字符串切分成有意义的词法单元。而什么字符能作为标识符的开头、什么字符能继续构成标识符在 Unicode 标准中有明确属性定义ID_Start可作为标识符起始与ID_Continue可继续构成标识符。该样例展示如何使用UnicodeCharacters类处理字符串中的 Unicode 属性并明确说明两点设计意图见 Samples/Unicode/README.md只聚焦类中一组属性方法IsIdStart、IsIdContinue、代理对相关方法因为同类方法的用法模式一致掌握一组即可举一反三特意演示了增补平面字符的处理——即超出基本多文种平面BMPU0000~UFFFF的码点如示例输入中的U20000CJK 扩展 B 区等字符它们在 UTF-16 中以代理对形式存在必须合并后才能正确判定 Unicode 属性。仓库中的实现cs/Scenario1_FindId.xaml.cs 与 cppwinrt/Scenario1_FindId.cpp将这一目标落成一个可运行的 UWP 页面用户在文本框中输入任意字符串点击Extract Identifiers按钮即可看到程序从中提取出的全部标识符列表。UnicodeCharacters 类与本文用到的核心 APIUnicodeCharacters位于Windows.Data.Text命名空间是 UWP 中全球化和本地化GlobalizationAndLocalization能力的一部分。它提供基于 Unicode 标准属性的字符查询方法本文涉及的五类方法及其语义如下均可在两种语言的示例源码中直接找到调用方法语义调用位置IsHighSurrogate(codepoint)判断码点是否为 UTF-16 高代理项UD800~UDBFF即代理对的前半部分C# 实现、C/WinRT 实现IsLowSurrogate(codepoint)判断码点是否为 UTF-16 低代理项UDC00~UDFFF即代理对的后半部分同上GetCodepointFromSurrogatePair(high, low)将高、低代理项合并还原为完整码点同上IsIdStart(codepoint)判断该字符是否满足 Unicode ID_Start 属性可作为标识符起始字符同上IsIdContinue(codepoint)判断该字符是否满足 Unicode ID_Continue 属性可继续构成标识符同上需要特别留意这些方法的入参名为codepoint但单次传入一个 UTF-16char16 位时它只是一个代码单元code unit而非完整码点。对于 BMP 内字符二者一致对于增补平面字符必须先用代理对方法把两个代码单元合并成真实码点再做属性判定——这正是本样例的核心难点所在。算法剖析FindIdsInString 如何分词标识符示例的核心逻辑是一个可复用的辅助方法FindIdsInString其注释清晰地定义了规则标识符以满足IsIdStart的字符开头后续由满足IsIdContinue的字符延续无效序列被忽略见 C# 版本与 C/WinRT 版本。整个算法是一个典型的单遍扫描状态机可拆解为三步第一步逐代码单元遍历合并代理对。每次循环取出当前charuint32_t/char按代码单元读取。若IsHighSurrogate为真则检查下一位是否满足IsLowSurrogate两者都满足时用GetCodepointFromSurrogatePair合成完整码点并把步进推进为 2若高代理后没有跟低代理则视为无效序列码点置 0 且只前进 1代码中留有 Warning: High surrogate not followed by low surrogate 注释见 C#。非代理字符直接前进 1。第二步标识符开始与延续判定。用indexIdStart记录当前标识符的起始下标初始为 -1C 中为std::wstring_view::npos当不在标识符内indexIdStart -1时若当前码点满足IsIdStart则记录起始位置当已在标识符内时若当前码点不满足IsIdContinue则说明标识符到此结束用Substring/substr截取并加入结果列表随后重置起始标记并将本字符下标回退一步重新处理因为当前字符可能是下一个标识符的起点。第三步收尾。循环结束后若仍有未结算的标识符字符串以标识符结尾补上最后一段。以共享 XAML 中默认输入框的文本为例见 shared/Scenario1_FindId.xamlHello, how are you? I hope you are ok! --id-- 1id 2id 3id id1 id2 id3 _CJK_B_1 _CJK_B_2 _CJK_B_3按 Unicode 标准的 ID_Start / ID_Continue 属性定义可以推断运行结果普通英文词Hello、how、are、you、I、hope、ok均以字母开头且全程为字母各自构成标识符--id--中-与不满足 ID_Start被跳过中间的id被提取1id 2id 3id中数字1不满足 ID_Start不能作为标识符开头因此提取出id每个词只提取id部分id1 id2 id3中数字属于 ID_Continue可延续标识符因此整体id1、id2、id3各是一个完整标识符_CJK_B_1这类增补平面字符先由代理对合并还原出码点 U20000其满足 ID_Start汉字/下划线均符合延续规则于是整个_CJK_B_1被识别为一个完整标识符——这一步正是对处理增补平面字符能力的直接验证。C# 实现逐行解读C# 版本位于 cs/Scenario1_FindId.xaml.cs方法签名与要点private ListString FindIdsInString(String inputString) { ListString idList new ListString(); int indexIdStart -1; // 标识符起始下标-1 表示当前不在标识符内 int i 0; while (i inputString.Length) { int nextIndex; uint codepoint inputString[i]; if (UnicodeCharacters.IsHighSurrogate(codepoint)) { if ((i inputString.Length) (UnicodeCharacters.IsLowSurrogate(inputString[i 1]))) { // 合并代理对还原增补平面码点 codepoint UnicodeCharacters.GetCodepointFromSurrogatePair( codepoint, inputString[i 1]); nextIndex i 2; } else { // 高代理未被低代理跟随无效序列忽略 codepoint 0; nextIndex i 1; } } else { nextIndex i 1; } if (indexIdStart -1) { if (UnicodeCharacters.IsIdStart(codepoint)) indexIdStart i; } else if (!UnicodeCharacters.IsIdContinue(codepoint)) { idList.Add(inputString.Substring(indexIdStart, i - indexIdStart)); indexIdStart -1; nextIndex i; // 回退一步重新检查当前字符 } i nextIndex; } if (indexIdStart ! -1) // 收尾字符串以标识符结尾 idList.Add(inputString.Substring(indexIdStart, i - indexIdStart)); return idList; }按钮事件Default_Click读取TextInput.Text调用该方法并用String.Join(, , results)将结果输出到TextOutput见 cs/Scenario1_FindId.xaml.cs。C/WinRT 实现同一算法的语言对照C/WinRT 版本位于 cppwinrt/Scenario1_FindId.cpp核心逻辑与 C# 完全一一对应仅换成 C/WinRT 惯用法入参为std::wstring_view返回std::vectorstd::wstring起始标记使用std::wstring_view::npos表示不在标识符内命名空间为Windows::Data::Text方法调用形式为UnicodeCharacters::IsHighSurrogate(...)、UnicodeCharacters::GetCodepointFromSurrogatePair(...)等按钮事件中通过TextInput().Text()读取、TextOutput().Text(result.str())写出并使用std::wstringstream以, 拼接结果见 cppwinrt/Scenario1_FindId.cpp。该工程通过 Project.idl 声明runtimeclass Scenario1_FindId : Windows.UI.Xaml.Controls.Page配合 Scenario1_FindId.h 完成 XAML 页面类的投影实现是标准的 C/WinRT 应用组织方式。Unicode.vcxproj还展示了工程级细节CharacterSet设为Unicode、启用预编译头pch.h、开启CppWinRTOptimized并依赖 NuGet 包Microsoft.Windows.CppWinRT版本 2.0.190404.8见 Unicode.vcxproj。XAML 界面与多语言共享结构页面布局存放在共享目录 shared/Scenario1_FindId.xamlC# 与 C/WinRT 工程各自通过项目文件引用这份共享 XAMLC# 侧见 Unicode.csprojC/WinRT 侧见 Unicode.vcxproj页面由三部分组成场景描述文本This scenario demonstrates how to use the UnicodeCharacters class in order to tokenize lexical identifiers within a string…输入TextBoxx:NameTextInput默认填充上节所示的多行测试文本触发按钮Extract Identifiers与结果TextBlockx:NameTextOutput。场景注册则通过各语言独立的配置完成C# 侧 SampleConfiguration.cs 定义FEATURE_NAME Unicode tokenization C# sample并注册场景Tokenize lexical identifiers within a stringC/WinRT 侧 SampleConfiguration.cpp 对应返回LUnicode C/WinRT Sample并注册同一场景。工程还引用了仓库根目录SharedContent下的共享模板App.xaml、MainPage、样式等见 Unicode.csproj这是本仓库所有 UWP 样例的统一外壳。构建与运行按 Samples/Unicode/README.md 中的说明该样例需要Visual Studio构建、Windows 10运行。具体步骤若以 ZIP 方式获取代码务必解压整个压缩包而不仅是样例所在文件夹——仓库中 SharedContent 目录是各样例共享的依赖路径缺失将导致构建失败启动 Visual Studio选择File Open Project/Solution进入 Samples/Unicode 目录按偏好语言打开对应解决方案C# 选 Unicode.sln工程 Unicode.csproj目标平台 10.0.22621.0C/WinRT 选 Unicode.sln工程 Unicode.vcxproj按CtrlShiftB或选择Build Build Solution完成构建仅部署时选择Build Deploy Solution调试运行按F5Debug Start Debugging免调试运行按CtrlF5Debug Start Without Debugging。运行后在输入框中粘贴或修改测试文本、点击Extract Identifiers即可观察分词结果特别是增补平面字符如被正确识别为标识符起始的过程。延伸相关参考与归档版本相关 API 参考为Windows.Data.Text.UnicodeCharacters类MSDN 文档 ID dn263490本文讲解的方法仅为该类的一个子集其余属性方法的用法模式与之相同可据此举一反三仓库 archived/Unicode/README.md 保留了该样例的 JavaScript现已归档与 C/CX 历史版本可对照查看同一场景在不同语言与旧工具链下的写法差异本样例归类于全球化和本地化GlobalizationAndLocalization能力集合同类场景如文本搜索、编辑器的标识符高亮均可直接复用FindIdsInString这套代理对合并 ID_Start/ID_Continue 判定的组合模式。赞分享示例工程【免费下载链接】Windows-universal-samplesAPI samples for the Universal Windows Platform.项目地址https://gitcode.com/gh_mirrors/wi/Windows-universal-samples点击查看免费下载相关推荐Scala 词法语法完全指南字符分类、标识符、字面量与换行规则Scala 词法语法完全指南字符分类、标识符、字面量与换行规则 本指南以 Scala 官方语言规范 spec/01 lexical syntax.md ht编程语言编译器标准库语言运行时如何测试Flutter官方插件espresso集成测试与platform interface单元测试实战含代码示例如何测试Flutter官方插件espresso集成测试与platform interface单元测试实战含代码示例 本文带你实战测试 Flutter 官方移动开发跨平台Windows-universal-samples 之 Simple3DGameDX用 DirectX 与 C 构建 UWP 第一人称 3D 游戏Windows universal samples 之 Simple3DGameDX用 DirectX 与 C 构建 UWP 第一人称 3D 游戏 本指南示例工程上一篇开源项目文档标准disposable-email-domains的README设计与维护指南下一篇【亲测免费】 WuMgrWindows更新管理工具创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考