Rust Unicode字符数据处理库ucd-parse的使用,解析UCD文件并提取Unicode字符属性信息

ucd-parse

一个用于将Unicode字符数据库(UCD)文件解析为结构化数据的库。

Build status crates.io

文档

许可证

该项目采用以下任一许可证授权:

  • 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”

链接

文档

docs.rs/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等)。

回到顶部