Rust文本断字库hyphenation的使用:支持多种语言的智能分词与连字符处理

Rust文本断字库hyphenation的使用:支持多种语言的智能分词与连字符处理

hyphenation是一个用于处理UTF-8字符串的断字库,支持多种语言。

[dependencies]
hyphenation = "0.8.3"

该库提供两种断字策略:

  1. 标准Knuth-Liang断字算法,使用TeX UTF-8模式构建的字典
  2. 扩展的(“非标准”)断字算法,基于László Németh的OpenOffice.org自动非标准断字技术,使用Libre/OpenOffice模式构建的字典

快速开始

hyphenation库依赖外部字典文件,需要加载到内存中。为方便起见,可以将字典嵌入到编译产物中。

[dependencies]
hyphenation = { version = "0.8.3", features = ["embed_all"] }

hyphenation顶层模块提供了一个小型的prelude,可以导入常用功能。

use hyphenation::*;

// 获取嵌入的美国英语字典,使用标准Knuth-Liang断字算法
let en_us = Standard::from_embedded(Language::EnglishUS)?;

// 在给定单词中识别有效断点
let hyphenated = en_us.hyphenate("hyphenation");

// 单词断点表示为字符串中的字节索引
let break_indices = &hyphenated.breaks;
assert_eq!(break_indices, &[2, 6, 7]);

// 可以迭代断字后的单词片段,标记或未标记
let marked = hyphenated.iter();
let collected : Vec<String> = marked.collect();
assert_eq!(collected, vec!["hy-", "phen-", "a-", "tion"]);

let unmarked = hyphenated.iter().segments();
let collected : Vec<&str> = unmarked.collect();
assert_eq!(collected, vec!["hy", "phen", "a", "tion"]);

// hyphenate()不区分大小写
let uppercase : Vec<_> = en_us.hyphenate("CAPIAL").into_iter().segments().collect();
assert_eq!(uppercase, vec!["CAP", "I", "TAL"]);

运行时加载字典

当前可用的字典集约占2.8MB数据。虽然可以嵌入字典,但大多数应用程序应该更喜欢在运行时加载单个字典:

let path_to_dict = "/path/to/en-us.bincode";
let english_us = Standard::from_path(Language::EnglishUS, path_to_dict)?;

文本分割

字典可以与文本分割结合使用,在文本运行中对单词进行断字。以下示例使用unicode-segmentation crate进行通用的Unicode分割。

use unicode_segmentation::UnicodeSegmentation;

let hyphenate_text = |text : &str| -> String {
    // 在单词边界上分割文本
    text.split_word_bounds()
        // 并对每个单词单独断字
        .flat_map(|word| en_us.hyphenate(word).into_iter())
        .collect()
};

let excerpt = "I know noble accents / And lucid, inescapable rhythms; […]";
assert_eq!("I know no-ble ac-cents / And lu-cid, in-escapable rhythms; […]"
          , hyphenate_text(excerpt));

完整示例代码

下面是一个完整的示例,展示如何使用hyphenation库进行多语言文本断字处理:

use hyphenation::*;
use unicode_segmentation::UnicodeSegmentation;

fn main() -> Result<(), hyphenation::Error> {
    // 加载美国英语字典(嵌入模式)
    let en_us = Standard::from_embedded(Language::EnglishUS)?;
    
    // 示例1: 基本单词断字
    let word = "hyphenation";
    let hyphenated = en_us.hyphenate(word);
    println!("{} 的断字结果: {:?}", word, hyphenated.breaks);
    println!("标记片段: {:?}", hyphenated.iter().collect::<Vec<_>>());
    println!("未标记片段: {:?}", hyphenated.iter().segments().collect::<Vec<_>>());
    
    // 示例2: 处理大写单词
    let uppercase_word = "CAPITAL";
    let uppercase_hyphenated = en_us.hyphenate(uppercase_word);
    println!("\n{} 的断字结果: {:?}", uppercase_word, uppercase_hyphenated.iter().segments().collect::<Vec<_>>());
    
    // 示例3: 文本段落断字
    let text = "The quick brown fox jumps over the lazy dog. Supercalifragilisticexpialidocious!";
    let hyphenate_text = |text: &str| -> String {
        text.split_word_bounds()
            .flat_map(|word| en_us.hyphenate(word).into_iter())
            .collect()
    };
    
    println!("\n原始文本: {}", text);
    println!("断字后文本: {}", hyphenate_text(text));
    
    Ok(())
}

许可证

hyphenation © 2016 tapeinosyne,双重许可:

  • Apache许可证,版本2.0
  • MIT许可证

各种断字模式文件有其各自的许可证,请参考原始文件获取详细信息。


1 回复

Rust文本断字库hyphenation的使用:支持多种语言的智能分词与连字符处理

hyphenation是一个高质量的Rust断字库,支持多种语言的智能分词和连字符处理。它基于TeX的断字算法,能够正确地处理多种语言的单词分割。

功能特点

  • 支持多种语言(英语、法语、德语、俄语等)
  • 基于词典的精确断字
  • 可配置的断字策略
  • 无运行时分配(no-std兼容)
  • 支持Unicode

使用方法

添加依赖

首先在Cargo.toml中添加依赖:

[dependencies]
hyphenation = "0.8"

基本使用示例

use hyphenation::{Language, Load, Standard};

fn main() {
    // 加载英语词典
    let en_us = hyphenation::Standard::from_embedded(Language::EnglishUS).unwrap();
    
    // 要断字的单词
    let word = "hyphenation";
    
    // 执行断字
    let hyphenated = word.hyphenate(&en_us).into_iter()
        .collect::<Vec<_>>();
    
    println!("{:?}", hyphenated); // 输出: ["hy", "phen", "ation"]
}

处理文本中的连字符

use hyphenation::{Language, Load, Standard};

fn main() {
    let text = "The quick brown fox jumps over the lazy dog.";
    let dictionary = Standard::from_embedded(Language::EnglishUS).unwrap();
    
    // 为文本中的单词添加连字符
    let hyphenated_text: String = text.split_whitespace()
        .map(|word| word.hyphenate(&dictionary).into_iter()
        .map(|segments| segments.join("-"))
        .collect::<Vec<_>>()
        .join(" ");
    
    println!("{}", hyphenated_text);
}

多语言支持示例

use hyphenation::{Language, Load, Standard};

fn main() {
    // 加载德语词典
    let de = Standard::from_embedded(Language::German1901).unwrap();
    
    let word = "Rechtschreibreform";
    let hyphenated = word.hyphenate(&de).into_iter()
        .collect::<Vec<_>>();
    
    println!("{:?}", hyphenated); // 输出: ["Recht", "schreib", "re", "form"]
}

自定义断字策略

use hyphenation::{Language, Load, Standard, Hyphenator};

fn main() {
    let dictionary = Standard::from_embedded(Language::EnglishUS).unwrap();
    let mut hyphenator = Hyphenator::new(dictionary);
    
    // 设置最小前缀和后缀长度
    hyphenator.min_prefix_length = 3;
    hyphenator.min_suffix_length = 3;
    
    let word = "international";
    let hyphenated = hyphenator.hyphenate(word).into_iter()
        .collect::<Vec<_>>();
    
    println!("{:?}", hyphenated); // 输出: ["int", "ern", "ation", "al"]
}

性能考虑

hyphenation库在第一次加载词典时会进行初始化,这个过程可能会有一些开销。对于需要高性能的场景,建议:

  1. 提前加载词典并缓存
  2. 对于已知语言环境,使用单例模式管理词典实例
  3. 考虑使用lazy_staticonce_cell来延迟初始化
use hyphenation::{Language, Standard};
use once_cell::sync::Lazy;

static EN_DICT: Lazy<Standard> = Lazy::new(|| {
    Standard::from_embedded(Language::EnglishUS).unwrap()
});

fn hyphenate_word(word: &str) -> Vec<String> {
    word.hyphenate(&EN_DICT).into_iter().collect()
}

支持的完整语言列表

hyphenation支持以下语言(通过Language枚举):

  • EnglishUS
  • EnglishGB
  • French
  • German1901
  • German1996
  • Russian
  • Ukrainian
  • 以及其他多种语言

可以通过hyphenation::Language枚举查看所有支持的语言。

注意事项

  1. 词典数据会增加二进制文件大小,如果空间受限,可以考虑按需加载
  2. 对于某些专业术语或新词,可能需要自定义词典
  3. 断字结果可能因语言变体而有所不同(如英式英语和美式英语)

完整示例代码

// 完整示例:使用hyphenation库处理多语言文本断字
use hyphenation::{Language, Load, Standard, Hyphenator};
use once_cell::sync::Lazy;

// 预加载常用语言词典
static EN_DICT: Lazy<Standard> = Lazy::new(|| {
    Standard::from_embedded(Language::EnglishUS).unwrap()
});
static FR_DICT: Lazy<Standard> = Lazy::new(|| {
    Standard::from_embedded(Language::French).unwrap()
});

fn main() {
    // 示例1: 英语文本断字
    let english_text = "The international organization";
    println!("Original English text: {}", english_text);
    
    let hyphenated_en: String = english_text.split_whitespace()
        .map(|word| {
            let segments: Vec<String> = word.hyphenate(&EN_DICT).into_iter().collect();
            segments.join("-")
        })
        .collect::<Vec<_>>()
        .join(" ");
    
    println!("Hyphenated English: {}", hyphenated_en);

    // 示例2: 法语文本断字
    let french_text = "L'organisation internationale";
    println!("\nOriginal French text: {}", french_text);
    
    let hyphenated_fr: String = french_text.split_whitespace()
        .map(|word| {
            let segments: Vec<String> = word.hyphenate(&FR_DICT).into_iter().collect();
            segments.join("-")
        })
        .collect::<Vec<_>>()
        .join(" ");
    
    println!("Hyphenated French: {}", hyphenated_fr);

    // 示例3: 自定义断字策略
    println!("\nCustom hyphenation strategy:");
    let mut hyphenator = Hyphenator::new(Standard::from_embedded(Language::EnglishUS).unwrap());
    hyphenator.min_prefix_length = 2;
    hyphenator.min_suffix_length = 2;
    
    let custom_word = "hyphenation";
    let custom_result = hyphenator.hyphenate(custom_word)
        .into_iter()
        .collect::<Vec<_>>();
    
    println!("'{}' hyphenated: {:?}", custom_word, custom_result);
}

这个完整示例展示了:

  1. 使用once_cell预加载多语言词典
  2. 处理英语和法语文本的断字
  3. 自定义断字策略的应用
  4. 完整的文本处理流程
回到顶部