Rust Unicode字符数据处理库ucd-parse的使用,解析UCD文件并提取Unicode字符属性信息
ucd-parse
一个用于将Unicode字符数据库(UCD)文件解析为结构化数据的库。
文档
许可证
该项目采用以下任一许可证授权:
- Apache License, Version 2.0
- MIT license 根据您的选择。
元数据
pkg:cargo/ucd-parse@0.1.13
over 1 year ago
v1.70.0
MIT OR Apache-2.0
28.9 KiB
安装
在您的项目目录中运行以下Cargo命令:
cargo add ucd-parse
或者将以下行添加到您的Cargo.toml中:
ucd-parse = “0.1.13”
链接
文档
仓库
github.com/BurntSushi/ucd-generate
所有者
Andrew Gallant (BurntSushi)
完整示例代码:
use std::fs::File;
use std::io::{BufRead, BufReader};
use ucd_parse::{UcdFile, UnicodeData};
fn main() -> Result<(), Box<dyn std::error::Error>> {
// 打开UnicodeData.txt文件
let file = File::open("UnicodeData.txt")?;
let reader = BufReader::new(file);
// 解析每一行数据
for line in reader.lines() {
let line = line?;
// 跳过空行和注释行
if line.trim().is_empty() || line.starts_with('#') {
continue;
}
// 解析Unicode字符数据
match UnicodeData::parse(&line) {
Ok(data) => {
println!("字符: {}", data.character);
println!("名称: {}", data.name);
println!("常规类别: {}", data.general_category);
println!("---");
}
Err(e) => {
eprintln!("解析错误: {}", e);
}
}
}
Ok(())
}
// 更完整的示例,展示如何解析不同类型的UCD文件
use ucd_parse::{BidiBrackets, BidiMirroring, ScriptExtensions, Script};
fn parse_ucd_files() -> Result<(), Box<dyn std::error::Error>> {
// 解析Scripts.txt
let script_file = File::open("Scripts.txt")?;
for line in BufReader::new(script_file).lines() {
if let Ok(script) = Script::parse(&line?) {
println!("脚本: {:?}", script);
}
}
// 解析ScriptExtensions.txt
let script_ext_file = File::open("ScriptExtensions.txt")?;
for line in BufReader::new(script_ext_file).lines() {
if let Ok(script_ext) = ScriptExtensions::parse(&line?) {
println!("脚本扩展: {:?}", script_ext);
}
}
// 解析BidiMirroring.txt
let bidi_mirror_file = File::open("BidiMirroring.txt")?;
for line in BufReader::new(bidi_mirror_file).lines() {
if let Ok(bidi_mirror) = BidiMirroring::parse(&line?) {
println!("双向镜像: {:?}", bidi_mirror);
}
}
// 解析BidiBrackets.txt
let bidi_brackets_file = File::open("BidiBrackets.txt")?;
for line in BufReader::new(bidi_brackets_file).lines() {
if let Ok(bidi_brackets) = BidiBrackets::parse(&line?) {
println!("双向括号: {:?}", bidi_brackets);
}
}
Ok(())
}
# Cargo.toml 依赖配置
[dependencies]
ucd-parse = "0.1.13"
1 回复
ucd-parse:Rust Unicode字符数据处理库
介绍
ucd-parse是一个专门用于解析Unicode字符数据库(UCD)文件的Rust库。它提供了简单易用的API来提取和处理Unicode字符的各种属性信息,包括字符名称、分类、大小写映射、数字值等元数据。
主要功能
- 解析UnicodeData.txt等标准UCD文件
- 提取字符属性信息
- 支持Unicode各种版本
- 高效的内存管理和解析性能
安装方法
在Cargo.toml中添加依赖:
[dependencies]
ucd-parse = "0.3"
基本使用方法
1. 解析单个字符属性
use ucd_parse::{UcdFile, UnicodeData};
fn main() -> Result<(), Box<dyn std::error::Error>> {
let data = "0041;LATIN CAPITAL LETTER A;Lu;0;L;;;;;N;;;;0061;";
let record: UnicodeData = data.parse()?;
println!("字符: {}", char::from_u32(record.codepoint.value()).unwrap());
println!("名称: {}", record.name);
println!("分类: {}", record.general_category);
Ok(())
}
2. 批量解析UCD文件
use std::fs::File;
use std::io::BufReader;
use ucd_parse::{UnicodeData, UcdFile};
fn parse_unicode_data() -> Result<(), Box<dyn std::error::Error>> {
let file = File::open("UnicodeData.txt")?;
let reader = BufReader::new(file);
for result in UnicodeData::from_read(reader)? {
let record = result?;
if record.general_category.abbrev() == "Lu" {
println!("大写字母: {} - {}",
char::from_u32(record.codepoint.value()).unwrap(),
record.name);
}
}
Ok(())
}
3. 提取特定字符属性
use ucd_parse::{UcdFile, UnicodeData};
fn get_character_properties(codepoint: u32) -> Result<(), Box<dyn std::error::Error>> {
// 假设已加载完整UCD数据
let records = UnicodeData::from_read(BufReader::new(File::open("UnicodeData.txt")?))?;
for record in records {
let record = record?;
if record.codepoint.value() == codepoint {
println!("字符属性:");
println!(" Codepoint: U+{:04X}", record.codepoint.value());
println!(" 名称: {}", record.name);
println!(" 分类: {}", record.general_category);
println!(" 双向类别: {}", record.bidi_class);
break;
}
}
Ok(())
}
高级用法
构建字符属性查询表
use std::collections::HashMap;
use ucd_parse::{UcdFile, UnicodeData};
fn build_unicode_map() -> Result<HashMap<char, UnicodeData>, Box<dyn std::error::Error>> {
let mut unicode_map = HashMap::new();
let file = File::open("UnicodeData.txt")?;
let reader = BufReader::new(file);
for result in UnicodeData::from_read(reader)? {
let record = result?;
if let Some(c) = char::from_u32(record.codepoint.value()) {
unicode_map.insert(c, record);
}
}
Ok(unicode_map)
}
处理其他UCD文件
ucd-parse还支持解析其他类型的UCD文件:
use ucd_parse::{UcdFile, PropList};
// 解析属性列表
fn parse_properties() -> Result<(), Box<dyn std::error::Error>> {
let file = File::open("PropList.txt")?;
let reader = BufReader::new(file);
for result in PropList::from_read(reader)? {
let prop = result?;
println!("属性: {} - 范围: {:?}", prop.property, prop.codepoints);
}
Ok(())
}
错误处理
use ucd_parse::{UcdFile, UnicodeData};
fn safe_parse() -> Result<(), Box<dyn std::error::Error>> {
match UnicodeData::from_read(BufReader::new(File::open("UnicodeData.txt")?)) {
Ok(records) => {
for record in records {
let record = record?;
// 处理记录
}
}
Err(e) => eprintln!("解析错误: {}", e),
}
Ok(())
}
性能建议
- 对于大型UCD文件,考虑使用迭代器而非一次性加载全部数据
- 使用缓冲读取器提高I/O性能
- 对于频繁查询,建议构建内存中的查找表
这个库为处理Unicode字符数据提供了强大而灵活的工具,特别适合需要深度Unicode支持的文本处理应用。
完整示例demo
//! ucd-parse库完整使用示例
//! 展示如何解析Unicode字符数据库并提取各种属性信息
use std::collections::HashMap;
use std::fs::File;
use std::io::BufReader;
use ucd_parse::{UcdFile, UnicodeData, PropList};
fn main() -> Result<(), Box<dyn std::error::Error>> {
println!("=== ucd-parse库使用示例 ===");
// 示例1: 解析单个字符属性
println!("\n1. 解析单个字符属性:");
parse_single_character()?;
// 示例2: 批量解析UCD文件
println!("\n2. 批量解析UnicodeData.txt文件:");
parse_unicode_data()?;
// 示例3: 构建字符属性查询表
println!("\n3. 构建字符属性查询表:");
let unicode_map = build_unicode_map()?;
println!("已构建包含 {} 个字符的查询表", unicode_map.len());
// 示例4: 查询特定字符属性
println!("\n4. 查询字符'A'的属性:");
if let Some(record) = unicode_map.get(&'A') {
println!("字符: A");
println!("名称: {}", record.name);
println!("分类: {}", record.general_category);
println!("Codepoint: U+{:04X}", record.codepoint.value());
}
// 示例5: 解析属性列表文件
println!("\n5. 解析PropList.txt文件:");
parse_properties()?;
Ok(())
}
/// 解析单个字符属性
fn parse_single_character() -> Result<(), Box<dyn std::error::Error>> {
// UnicodeData.txt文件中的一行数据示例
let data = "0041;LATIN CAPITAL LETTER A;Lu;0;L;;;;;N;;;;0061;";
let record: UnicodeData = data.parse()?;
println!("字符: {}", char::from_u32(record.codepoint.value()).unwrap());
println!("名称: {}", record.name);
println!("分类: {}", record.general_category);
println!("简单大写映射: {:?}", record.simple_uppercase_mapping);
println!("简单小写映射: {:?}", record.simple_lowercase_mapping);
Ok(())
}
/// 批量解析UnicodeData.txt文件
fn parse_unicode_data() -> Result<(), Box<dyn std::error::Error>> {
// 假设当前目录下有UnicodeData.txt文件
let file = File::open("UnicodeData.txt")?;
let reader = BufReader::new(file);
let mut uppercase_count = 0;
let mut lowercase_count = 0;
let mut digit_count = 0;
for result in UnicodeData::from_read(reader)? {
let record = result?;
match record.general_category.abbrev() {
"Lu" => uppercase_count += 1, // 大写字母
"Ll" => lowercase_count += 1, // 小写字母
"Nd" => digit_count += 1, // 十进制数字
_ => {}
}
}
println!("统计结果:");
println!(" 大写字母数量: {}", uppercase_count);
println!(" 小写字母数量: {}", lowercase_count);
println!(" 十进制数字数量: {}", digit_count);
Ok(())
}
/// 构建字符到UnicodeData的映射表
fn build_unicode_map() -> Result<HashMap<char, UnicodeData>, Box<dyn std::error::Error>> {
let mut unicode_map = HashMap::new();
let file = File::open("UnicodeData.txt")?;
let reader = BufReader::new(file);
for result in UnicodeData::from_read(reader)? {
let record = result?;
if let Some(c) = char::from_u32(record.codepoint.value()) {
unicode_map.insert(c, record);
}
}
Ok(unicode_map)
}
/// 解析属性列表文件
fn parse_properties() -> Result<(), Box<dyn std::error::Error>> {
// 假设当前目录下有PropList.txt文件
let file = File::open("PropList.txt")?;
let reader = BufReader::new(file);
let mut property_count = 0;
for result in PropList::from_read(reader)? {
let prop = result?;
property_count += 1;
if property_count <= 5 { // 只显示前5个属性
println!("属性 {}: {} - 范围: {:?}", property_count, prop.property, prop.codepoints);
}
}
println!("总共发现 {} 个属性", property_count);
Ok(())
}
/// 安全的错误处理示例
fn safe_unicode_parsing() -> Result<(), Box<dyn std::error::Error>> {
match UnicodeData::from_read(BufReader::new(File::open("UnicodeData.txt")?)) {
Ok(records) => {
for record in records {
match record {
Ok(record) => {
// 在这里处理每个Unicode记录
if record.codepoint.value() == 0x0041 {
println!("找到字符A: {}", record.name);
}
}
Err(e) => eprintln!("记录解析错误: {}", e),
}
}
}
Err(e) => eprintln!("文件解析错误: {}", e),
}
Ok(())
}
这个完整示例展示了ucd-parse库的主要功能,包括:
- 单个字符属性解析
- 批量文件处理
- 字符属性映射表构建
- 属性列表文件解析
- 错误处理机制
使用前请确保在当前目录下有相应的UCD文件(UnicodeData.txt、PropList.txt等)。