中文是超過10億人以上使用的語言,以地區來分的話大致可以分為繁體中文與簡體中文,其中的繁體中文又可以再分為台灣正體和香港繁體。台灣正體、香港繁體和簡體中文除了字形上會有差異之外(例如「體」和「体」),用語也是稍有不同(例如「程式」和「程序」、「軟體」和「软件」),所以使用程式語言處理中文地區轉換,並不是一件容易的事情。還好,有一個以C++程式語言為基礎所開發出來的開源工具──OpenCC,可以協助我們在Rust程式語言上實現繁體中文和簡體中文的轉換。
OpenCC GitHub連結:
OpenCC Rust
「OpenCC Rust」是筆者開發的套件,可以讓Rust程式綁定OpenCC的函式庫,使Rust程式能夠直接使用OpenCC函式庫的功能。
Crates.io
Cargo.toml
編譯
OpenCC是使用C++程式語言開發的,因此無法直接被引用至Rust程式中使用,必須要使用這篇文章介紹的做法來引用才行。為了簡化問題,「OpenCC Rust」套件可以自動綁定作業系統中安裝的OpenCC函式庫。如果想要手動設定OpenCC函式庫的位置也是可以的,尤其是想要讓Rust程式可以在無OpenCC函式庫的執行環境中使用,要先設定好以下的幾個環境變數:
-
OPENCC_LIB_DIRS
:函式庫檔案所在的目錄位置。這個變數類似C/C++編譯器中-L
參數的用途。路徑如果有多個的話,必須使用:
隔開。 -
OPENCC_LIBS
:函式庫的名稱。這個變數類似C/C++編譯器中-l
參數的用途。路徑如果有多個的話,必須使用:
隔開。通常這個變數的值是opencc
。 -
OPENCC_INCLUDE_DIRS
:函式庫標頭檔的路徑。這個變數類似C/C++編譯器中-i
參數的用途。路徑如果有多個的話,必須使用:
隔開。 -
OPENCC_STATIC
:是否要使用static
(靜態連結),否則就使用dylib
來編譯。 -
OPENCC_DYLIB_STDCPP
:如果要使用static
來編譯,且OpenCC函式庫是用GNU C/C++編譯器編譯出來的話,這個環境變數應該要被設定成1
,讓Rust程式能夠和stdc++
函式庫作連結。 -
OPENCC_STATIC_STDCPP
:如果要使用static
來編譯,且OpenCC函式庫是用musl libc編譯器編譯出來的話,這個環境變數應該要被設定成1
,讓Rust程式能夠和stdc++
函式庫作連結。
使用方法
opencc_rust
這個crate底下有OpenCC
結構體,這個結構體的實體提供了convert
和convert_to_buffer
方法,可以將從參數傳入的字串轉換成其它字串。至於轉換的規則則是在一開始建立OpenCC
結構實體的時候就必須決定好。opencc_rust
這個crate已經有內建了OpenCC預設的轉換規則,以DefaultConfig
這個列舉來表示。在使用OpenCC
結構體的new
關聯函數來建立OpenCC
結構實體的時候,除了可以傳入轉換規則的設定檔(如s2t.json
、t2s.json
等)之外,還可以傳入DefaultConfig
列舉的變體實體。
以下是繁體中文轉簡體中文的範例:
use opencc_rust::*;
let opencc = OpenCC::new(DefaultConfig::TW2SP).unwrap();
let s = opencc.convert("涼風有訊");
assert_eq!("凉风有讯", &s);
let s = opencc.convert_to_buffer(",秋月無邊", s);
assert_eq!("凉风有讯,秋月无边", &s);
以下是簡體中文轉繁體中文的範例:
use opencc_rust::*;
let opencc = OpenCC::new(DefaultConfig::S2TWP).unwrap();
let s = opencc.convert("凉风有讯");
assert_eq!("涼風有訊", &s);
let s = opencc.convert_to_buffer(",秋月无边", s);
assert_eq!("涼風有訊,秋月無邊", &s);
OpenCC內建的轉換規則有以下幾種,都已列在DefaultConfig
列舉中:
- S2T:簡體轉繁體。
- T2S:繁體轉簡體。
- S2TW:簡體轉台灣正體。
- TW2S:台灣正體轉簡體。
- S2HK:簡體轉香港繁體。
- HK2S:香港繁體轉簡體。
- S2TWP:簡體轉台灣正體,允許慣用語轉換。
- TW2SP:台灣正體轉簡體,允許慣用語轉換。
- T2TW:繁體轉台灣正體。
- T2HK:繁體轉香港繁體。
靜態字典檔
OpenCC的轉換規則其實就是從檔案系統中引入多個不同的字典檔來進行字串對應,而字典檔由於OpenCC函式庫本身設計的關係,只能存在於檔案系統中使用。也就是說,即便我們將OpenCC的函式庫以靜態連結的方式與我們的Rust程式進行編譯,Rust程式在沒有OpenCC函式庫的執行環境下,還是需要額外的OpenCC字典檔才能夠執行。如果要連OpenCC的字典檔都「靜態化」,就只能將OpenCC的字典檔與Rust程式編譯在一起後,在使用OpenCC前,再把OpenCC字典檔複製到檔案系統中了。
為了簡化這個問題,可以啟用「OpenCC Rust」套件的static-dictionaries
特色,Cargo.toml
設定檔的寫法如下:
[dependencies.opencc-rust]
version = "*"
features = ["static-dictionaries"]
啟用static-dictionaries
特色之後,在建立出OpenCC
結構實體前,就能先使用opencc-rust
這個crate底下的generate_static_dictionary
函數,把需要用到的字典檔先複製到指定的目錄位置之下。舉例來說:
use opencc_rust::*;
let output_path = "/path/to/dictionaries-directory";
generate_static_dictionary(&output_path, DefaultConfig::TW2SP).unwrap();
let opencc = OpenCC::new(Path::join(&output_path, DefaultConfig::TW2SP)).unwrap();
assert_eq!("凉风有讯", &opencc.convert("涼風有訊"));