Rust插件库tr的使用:高效文本处理与翻译工具库

Rust插件库tr的使用:高效文本处理与翻译工具库

Rust应用程序的本地化

这个仓库提供了用于本地化Rust应用程序的工具,使您的软件更容易翻译成不同的语言。

有两个crate:

  • tr 是一个运行时库,包装了gettext(目前),以提供一种方便的方式来本地化应用程序。
  • xtr 是一个类似于GNU的xgettext的二进制文件,用于从Rust crate中提取字符串。

如何翻译Rust应用程序

  1. 使用适当的宏/函数注释源代码中的字符串。您可以使用:

    • 这个tr crate中的tr!宏(仍在开发中),或者
    • gettextgettext-rs crate中的gettext函数
  2. 在您的crate上运行xtr程序,将字符串提取到.pot文件中

  3. 使用GNU gettext工具来合并、翻译和生成.mo文件

关于tr!

  • 名称来自Qt的tr()函数。这是一个短名称,因为它将放在大多数字符串字面量上。
  • 宏可以进行Rust风格的格式化。这使得可以在翻译中重新排序参数。
  • Hello {}Hello {0}Hello {name}都可以工作。
  • 目前,默认后端使用gettext-rs crate,但这可能会在未来更改为gettext
  • 复数形式由gettext处理,它支持多种语言的不同复数形式。

示例代码

#[macro_use]
extern crate tr;
fn main() {
    // 使用tr_init宏告诉gettext在哪里查找翻译
    tr_init!("/usr/share/locale/");
    let folder = if let Some(folder) = std::env::args().nth(1) {
        folder
    } else {
        println!("{}", tr!("Please give folder name"));
        return;
    };
    match std::fs::read_dir(&folder) {
        Err(e) => {
            println!("{}", tr!("Could not read directory '{}'\nError: {}",
                                folder, e));
        }
        Ok(r) => {
            // 单数/复数形式
            println!("{}", tr!(
                "The directory {} has one file" | "The directory {} has {n} files" % r.count(),
                folder
            ));
        }
    }
}

完整示例demo

// 引入tr宏
#[macro_use]
extern crate tr;

fn main() {
    // 初始化翻译路径 - 实际使用时替换为您的翻译文件路径
    tr_init!("/usr/share/locale/");
    
    // 简单的翻译示例
    println!("{}", tr!("Welcome to our application"));
    
    // 带参数的翻译
    let username = "Alice";
    println!("{}", tr!("Hello, {name}", name = username));
    
    // 复数形式处理
    let file_count = 5;
    println!("{}", tr!(
        "Found one file" | "Found {n} files" % file_count
    ));
    
    // 错误消息翻译
    match std::fs::File::open("nonexistent.txt") {
        Ok(_) => println!("{}", tr!("File opened successfully")),
        Err(e) => println!("{}", tr!("Error opening file: {error}", error = e)),
    }
}

关于xtr

xtr是一个从Rust crate的源代码中提取翻译字符串的工具。该工具应该与任何基于gettext的函数兼容。但已添加了对tr!宏特殊语法的支持。

使用方式

xtr src/main.rs -o example.pot

这将从所有crate模块中提取字符串并创建文件example.pot。您现在可以使用gettext工具来翻译这个文件。

许可证

  • tr crate根据MIT许可证授权
  • xtr程序仅用于开发,采用GNU Affero通用公共许可证(AGPL)

1 回复

Rust插件库tr的使用:高效文本处理与翻译工具库

tr是一个Rust编写的文本处理和翻译工具库,它提供了简单高效的API来处理字符串转换、翻译和文本操作任务。

主要特性

  • 轻量级且高性能的文本处理
  • 支持字符替换、删除和转换操作
  • 类似Unix tr命令的功能,但更强大
  • 支持Unicode字符处理
  • 提供链式API调用

安装方法

在Cargo.toml中添加依赖:

[dependencies]
tr = "0.1"

基本使用方法

1. 简单字符替换

use tr::tr;

fn main() {
    let result = tr("aeiou", "AEIOU", "hello world");
    println!("{}", result); // 输出: hEllO wOrld
}

2. 删除指定字符

use tr::tr;

fn main() {
    let result = tr("-d", "aeiou", "hello world");
    println!("{}", result); // 输出: hll wrld
}

3. 压缩重复字符

use tr::tr;

fn main() {
    let result = tr("-s", "l", "hello world");
    println!("{}", result); // 输出: helo world
}

高级用法

1. 字符集范围

use tr::tr;

fn main() {
    let result = tr("a-z", "A-Z", "Hello 123");
    println!("{}", result); // 输出: HELLO 123
}

2. 组合操作

use tr::tr;

fn main() {
    let result = tr("-ds", "aeiou", "hello world");
    println!("{}", result); // 输出: hll wrld
}

3. 自定义转换函数

use tr::tr_fn;

fn main() {
    let result = tr_fn(|c| if c == 'l' { '1' } else { c }, "hello world");
    println!("{}", result); // 输出: he11o wor1d
}

实际应用示例

1. 电话号码格式化

use tr::tr;

fn format_phone_number(input: &str) -> String {
    tr("-d", " -()", input) // 先删除所有分隔符
     .chars()
     .enumerate()
     .map(|(i, c)| match i {
         0 => format!("({}", c),
         3 => format!(") {}", c),
         6 => format!("-{}", c),
         _ => c.to_string()
     })
     .collect()
}

fn main() {
    let phone = "1234567890";
    println!("{}", format_phone_number(phone)); // 输出: (123) 456-7890
}

2. 简单ROT13加密

use tr::tr;

fn rot13(input: &str) -> String {
    tr("a-zA-Z", "n-za-mN-ZA-M", input)
}

fn main() {
    let secret = "Hello World";
    let encoded = rot13(secret);
    println!("Encoded: {}", encoded); // 输出: Uryyb Jbeyq
    
    let decoded = rot13(&encoded);
    println!("Decoded: {}", decoded); // 输出: Hello World
}

性能提示

  • 对于大量文本处理,考虑使用tr::translate函数直接操作&mut str以避免分配
  • 预编译常用转换模式可以提高性能

tr库是Rust生态中处理文本转换任务的轻量级解决方案,特别适合需要高效字符级操作的场景。

完整示例demo

下面是一个结合了多种功能的完整示例,展示如何使用tr库进行复杂的文本处理:

use tr::{tr, tr_fn};

fn main() {
    // 示例1: 基础字符替换
    let text = "rust programming is fun";
    let replaced = tr("aeiou", "AEIOU", text);
    println!("替换元音字母: {}", replaced); // 输出: rUst prOgrAmmIng Is fUn

    // 示例2: 删除特定字符并压缩空格
    let messy_text = "  Hello,,,  World!!  ";
    let cleaned = tr("-ds", " ,!", messy_text);
    println!("清理后的文本: {}", cleaned); // 输出: HelloWorld

    // 示例3: 自定义转换函数
    let custom_text = "Password123";
    let obscured = tr_fn(|c| {
        match c {
            'a'..='z' => '*',
            'A'..='Z' => '*',
            _ => c
        }
    }, custom_text);
    println!("密码模糊处理: {}", obscured); // 输出: ********123

    // 示例4: 组合操作 - 格式化用户输入
    let user_input = "  jOHN dOE  ";
    let formatted = tr("a-z", "A-Z", &tr("-s", " ", user_input.trim()));
    println!("格式化姓名: {}", formatted); // 输出: JOHN DOE

    // 示例5: 高级应用 - 创建简单的加密器
    fn simple_cipher(text: &str, shift: u8) -> String {
        tr_fn(|c| {
            if c.is_ascii_alphabetic() {
                let base = if c.is_ascii_lowercase() { b'a' } else { b'A' };
                ((((c as u8 - base + shift) % 26) + base) as char)
            } else {
                c
            }
        }, text)
    }
    
    let message = "Meet me at 5 PM";
    let encrypted = simple_cipher(message, 3);
    println!("加密消息: {}", encrypted); // 输出: Phhw ph dw 5 SP
    let decrypted = simple_cipher(&encrypted, 23); // 26-3=23
    println!("解密消息: {}", decrypted); // 输出: Meet me at 5 PM
}

这个完整示例展示了tr库在实际应用中的多种用法,包括基础字符替换、文本清理、自定义转换、组合操作以及创建一个简单的加密/解密工具。

回到顶部