dotnet 简单使用 ICU 库进行分词和分行

news/2024/12/23 7:10:16/文章来源:https://www.cnblogs.com/lindexi/p/18622917

按照 dotnet 的惯例,先使用 NuGet 安装大佬封装好的 ICU 库,我这里选择的是 icu.net 库和 Microsoft.ICU.ICU4C.Runtime 库。其中 icu.net 库提供 ICU 的 dotnet 层封装,让咱上层 C# 代码可以方便调用。而 Microsoft.ICU.ICU4C.Runtime 库则提供非托管的 dll 依赖,用于提供 ICU 的实际逻辑和辅助数据,包括 icuuc72.dll 、icuin72.dll 和 icudt72.dll 文件

需要说明的是,默认情况下,系统在 C:\windows\System32\ 文件夹里面都带有 icuuc.dll 和 icuin.dll 文件,只是没有带包含 ICU 的 data file 的 icudt72.dll 文件。默认情况下 dotnet 都会使用系统自带的 dll 文件。在本文这里需要使用 Microsoft.ICU.ICU4C.Runtime 只是为了用到更多的功能,如分词和分行功能而已

安装完成的 icu.net 库和 Microsoft.ICU.ICU4C.Runtime 库之后的 csproj 项目文件内容大概如下

<Project Sdk="Microsoft.NET.Sdk"><PropertyGroup><OutputType>Exe</OutputType><TargetFramework>net9.0</TargetFramework><ImplicitUsings>enable</ImplicitUsings><Nullable>enable</Nullable></PropertyGroup><ItemGroup><PackageReference Include="icu.net" Version="3.0.0" /><PackageReference Include="Microsoft.ICU.ICU4C.Runtime" Version="72.1.0.3" /></ItemGroup></Project>

在使用 ICU 之前,需要调用 Icu.Wrapper.Init(); 方法。完全使用完成之后,建议调用 Icu.Wrapper.Cleanup(); 方法。对于很多应用程序来说,都是从一打开就使用的,直到进程退出。这时候就可以不调用 Icu.Wrapper.Cleanup(); 方法了。只有对于一些是中间过程中使用 ICU 的逻辑,才需要成对调用

Icu.Wrapper.Init();// 逻辑开始Icu.Wrapper.Cleanup();

当然了,如果为了安全性考虑,可以将 Icu.Wrapper.Cleanup(); 放到 finally 方法里面哈

以上就是所有的准备工作,接下来就是实际功能的演示

先和大家演示分词功能,测试代码如下

Span<string> testTextSpan = ["大学生活", "大学生活动", "大学生命"];foreach (var testText in testTextSpan)
{Console.WriteLine($"对 '{testText}' 进行分词:");foreach (var boundary in Icu.BreakIterator.GetBoundaries(BreakIterator.UBreakIteratorType.WORD,Locale.GetLocaleForLCID(CultureInfo.CurrentCulture.LCID), testText)){var subText = testText.AsSpan().Slice(boundary.Start, boundary.End - boundary.Start);Console.WriteLine($" - \"{subText.ToString()}\"");}
}

我这里选用了中文不简单的分词句子来进行测试,运行代码,可见控制台如下输出

分词测试:
对 '大学生活' 进行分词:- "大学"- "生活"
对 '大学生活动' 进行分词:- "大学生"- "活动"
对 '大学生命' 进行分词:- "大学"- "生命"

可以看到分词策略还是不错的

继续演示 分行 的功能。分行的功能是常见在文本排版布局里面使用,在咱中文里面大概的核心用途就是防止标点符号被错误分行,如将逗号放在行首,将 左引号放在行末等错误排版问题。在英文里面则是避免一个单词被强行拆分为两行。不同的国家语言文化有不同的规则,于是才有了 ICU 库的整理规范

如以下测试代码

Console.WriteLine($"分行测试:");var text = "asd fx, aasa “说话大学生上课”\nasd sadf";
var boundaries = Icu.BreakIterator.GetBoundaries(BreakIterator.UBreakIteratorType.LINE,Locale.GetLocaleForLCID(CultureInfo.CurrentCulture.LCID), text);
foreach (Boundary boundary in boundaries)
{var subText = text.AsSpan().Slice(boundary.Start, boundary.End - boundary.Start);Console.WriteLine($" - \"{subText.ToString()}\"");
}

控制台输出如下

分行测试:- "asd "- "fx, "- "aasa "- "“说"- "话"- "大"- "学"- "生"- "上"- "课”
"- "asd "- "sadf"

可以看到以上的分行策略是正确的,可以将英文单词合并到一个 Boundary 里面,将标点符号和对应的文字也合并到一个 Boundary 里面

但尽管如此,在中文排版里面,如果严格执行 GB/T 15834 标准,那 ICU 库还是很有挑战的,且更挑战的是文本库哈。详细请看 Office 文档 文本排版布局 中华人民共和国国家标准 标点符号用法

除此之外,咱还可以使用 ICU 库进行转义,如以下测试例子

// Will output "NFC form of XA\u0308bc is XÄbc"
// 有些控制台输出不了 Ä 字符哦
Console.WriteLine($"NFC form of XA\\u0308bc is {Icu.Normalizer.Normalize("XA\u0308bc",Icu.Normalizer.UNormalizationMode.UNORM_NFC)}");

本文代码放在 github 和 gitee 上,可以使用如下命令行拉取代码。我整个代码仓库比较庞大,使用以下命令行可以进行部分拉取,拉取速度比较快

先创建一个空文件夹,接着使用命令行 cd 命令进入此空文件夹,在命令行里面输入以下代码,即可获取到本文的代码

git init
git remote add origin https://gitee.com/lindexi/lindexi_gd.git
git pull origin c060ecede2ffa8b81c57e1ff8d0efcb0820fafc4

以上使用的是国内的 gitee 的源,如果 gitee 不能访问,请替换为 github 的源。请在命令行继续输入以下代码,将 gitee 源换成 github 源进行拉取代码。如果依然拉取不到代码,可以发邮件向我要代码

git remote remove origin
git remote add origin https://github.com/lindexi/lindexi_gd.git
git pull origin c060ecede2ffa8b81c57e1ff8d0efcb0820fafc4

获取代码之后,进入 Workbench/FichallbibaRenafawwhi 文件夹,即可获取到源代码

更多技术博客,请参阅 博客导航

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/857280.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

读图数据库实战笔记11读后总结与感想兼导读

读后总结与感想1. 基本信息 图数据库实战[ [美] 戴夫贝克伯杰(Dave Bechberger) (美) 乔希佩里曼著人民邮电出版社,2021年10月出版1.1. 读薄率 书籍总字数413千字,笔记总字数30938字。 读薄率30938413000≈7.49% 1.2. 读厚方向Data Mesh权威指南数据的边界:隐私与个人数据保护…

12.16 ~ 12.22

菜12.16 回归 OI 第一天。 打多校的模拟赛。 3 题 4.5h,已经是省选模拟了 T1 一眼可反悔贪心好像还是道原,于是在场上与 T1 大战 3h 遗憾离场 后边两题直接敲暴力了 T3 还是个构造,这下一点不会了 然后 T1 的 DP 出了点小锅,在新 OJ 绑包以及选手可以自行加点的情况下取得了…

给销售人

许多人不懂的是:销售最大的收获不是提成多少,不是升职,不是增加了炫耀的资本,不是完成任务,销售最大的收获是:你生活中多了一个信任你的人! 销售最大的敌人 不是对手,不是价格太高,不是拒绝你的客户,不是公司制度,不是产品不好,最大的敌人是:你的抱怨!你的借口!…

pve系统all in one 搭建

成功安装系统,硬件不支持8.x的pve 使用5.1 后续可以更新 换源 在更新软件包时出错因为 Proxmox 的 Ceph Quincy 源未正确导入公钥,导致系统无法验证其软件包的签名。重新更新成功 安装最新配置 过程中顺便加了一个pcie x1 转1g的网卡,不知是否需要驱动。使用的时候再看吧 不…

使用ollama+llama3.1+open-webui搭一个本地的模型

1、先安装我们的ollama 1.1、官网地址:https://ollama.com/ 选择合适的版本,我的是window版本,点击下载,不用填邮箱。1.2、开始安装,选择默认就可以1.3、安装完毕:cmd输入:ollama2、安装模型:llama3.1 2.1:找到模型 2.2复制下载2.3、命令行下载: 2.4、下载完毕就进入对…

windows修改mac 地址

参考 https://blog.csdn.net/u012559967/article/details/134768073 win11确认可行 (另外一种修改注册表,暂未确认) 网络适配器中配置 网络适配器中配置的方式适用于能够在网络适配器中找到物理地址(NetworkAddress)的情况。 1、打开控制面板 > 网络和共享中心 > 更改…

MADDPG算法

MADDPG算法 论文名称:《Multi-Agent Actor-Critic for Mixed Cooperative-Competitive Environments》 一、基本问题 MADDPG是一篇经典的多智能体强化学习算法。在MADDPG以前,多智能体强化学习算法主要为独立学习技术。独立学习技术 独立学习技术就是在环境中对于每一个智能体…

ble广播和连接

蓝牙BLE设备的状态:从机处于待机,广播,连接状态中的一种,主机处于待机,扫描,连接状态的一种。 在BLE通讯中,数据收发都是通过连接事件触发的。连接事件的发生始终位于一个频率,这个频率由连接参数决定。连接参数是主机决定的,从机可以向主机发起连接参数请求,但是最终…

ble基础

一、蓝牙基础 蓝牙标准profile bluez linux tools 一文读懂BLE 1.1 蓝牙分类 蓝牙分为经典蓝牙(BT-Bluetooth)和低功耗蓝牙(BLE-Bluetooth Low Energy)。这两套原理和实现都不一样,也无法实现互通。 Basic Rate(BR)/EDR/AMP 最初的蓝牙技术,包括可选的EDR(Enhanced Da…

爬取小说案例-BeautifulSoup教学篇

@目录前言导航BeautifulSoupBeautifulSoup介绍BeautifulSoup的使用1. 导入库2. 实例化对象3. 提取数据成果共勉博客 前言 当我们进行爬取各种资源,拿到源码进行解析数据的时候,会用到各种解析方式,本文介绍的爬取小说的一个案例,使用比较受欢迎的python第三方库BeautifuSou…

vue基础指令示例

1、vue基础示例<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>基础指令</title><script src="../vu/js/vue.js"></script><style>.box1{width: 150px;height: 1…

楚慧杯Misc—复现

gza_CrackerCrack_me 追踪tcp流量找到字典保存字典,上流量一把梭base64解密特殊流量2 一把梭出个www.zip打开,是个RSA <?php $cmd = @$_POST[ant]; $pk = <<<EOF -----BEGIN PUBLIC KEY----- MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCfhiyoPdM6svJZ+QlYywklwVcx…