zhconv-rs — 中文简繁及地區詞轉換
zhconv-rs converts Chinese between Traditional, Simplified and regional variants, using rulesets sourced from MediaWiki/Wikipedia and OpenCC, which are merged, flattened and prebuilt into Aho‑Corasick automata for single-pass, linear-time conversions.
🔗 Web app (wasm): https://zhconv.pages.dev
⚙️ Cli: npx @zhconv/cli zh-tw < input.txt or npx @zhconv/cli-opencc for additional OpenCC dictionaries. Alternatively, cargo install zhconv or downlaod from releases.
🦀 Rust crate: cargo add zhconv (see docs for details)
use zhconv::{zhconv, Variant};
assert_eq!(zhconv("雾失楼台,月迷津渡", Variant::ZhTW), "霧失樓臺,月迷津渡");
assert_eq!(zhconv("驛寄梅花,魚傳尺素", "zh-Hans".parse().unwrap()), "驿寄梅花,鱼传尺素");
🐍 Python package: pip install zhconv-rs or pip install zhconv-rs-opencc (for additional OpenCC dictionaries)
from zhconv_rs import zhconv
assert zhconv("天干物燥 小心火烛", "zh-tw") == "天乾物燥 小心火燭"
More usage
assert zhconv("《-{zh-hans:三个火枪手;zh-hant:三劍客;zh-tw:三劍客}-》是亞歷山大·仲馬的作品。", "zh-cn", mediawiki=True) == "《三个火枪手》是亚历山大·仲马的作品。"
assert zhconv("-{H|zh-cn:雾都孤儿;zh-tw:孤雛淚;zh-hk:苦海孤雛;zh-sg:雾都孤儿;zh-mo:苦海孤雛;}-《雾都孤儿》是查尔斯·狄更斯的作品。", "zh-tw", True) == "《孤雛淚》是查爾斯·狄更斯的作品。"
# Customize conversion tables:
from zhconv_rs import make_converter
assert make_converter(None, [("天", "地"), ("水", "火")])("甘肅天水") == "甘肅地火"
import io
convert = make_converter("zh-hans", io.StringIO("䖏 处\n罨畫 掩画")) # or path to rule file
assert convert("秀州西去湖州近 幾䖏樓臺罨畫間") == "秀州西去湖州近 几处楼台掩画间"
🧩 API demo: https://zhconv.bamboo.workers.dev
Node.js package: npm install zhconv or yarn add zhconv
JS in browser: https://cdn.jsdelivr.net/npm/zhconv-web@latest
HTML snippet
<script type="module">
// Use ES module import syntax to import functionality from the module
// that we have compiled.
//
// Note that the `default` import is an initialization function which
// will "boot" the module and make it ready to use. Currently browsers
// don't support natively imported WebAssembly as an ES module, but
// eventually the manual initialization won't be required!
import init, { zhconv } from 'https://cdn.jsdelivr.net/npm/zhconv-web@latest/zhconv.js'; // specify a version tag if in prod
async function run() {
await init();
alert(zhconv(prompt("Text to convert to zh-hans:"), "zh-hans"));
}
run();
</script>
Variants and conversion tables
Unlike OpenCC, whose dictionaries are bidirectional (e.g., s2t, tw2s), zhconv-rs follows MediaWiki’s approach and provides one conversion table per target variant:
zh-Hant, zh-Hans, zh-TW, zh-HK, zh-MO, zh-CN, zh-SG, zh-MY
| Target | Tag | Script | Description |
|---|---|---|---|
| Simplified Chinese / 简体中文 | zh-Hans |
SC / 简 | W/O substituing region-specific phrases. |
| Traditional Chinese / 繁體中文 | zh-Hant |
TC / 繁 | W/O substituing region-specific phrases. |
| Chinese (Taiwan) / 臺灣正體 | zh-TW |
TC / 繁 | With Taiwan-specific phrases adapted. |
| Chinese (Hong Kong) / 香港繁體 | zh-HK |
TC / 繁 | With Hong Kong-specific phrases adapted. |
| Chinese (Macau) / 澳门繁體 | zh-MO |
TC / 繁 | Same as zh-HK for now. |
| Chinese (Mainland China) / 大陆简体 | zh-CN |
SC / 简 | With mainland China-specific phrases adapted. |
| Chinese (Singapore) / 新加坡简体 | zh-SG |
SC / 简 | Same as zh-CN for now. |
| Chinese (Malaysia) / 大马简体 | zh-MY |
SC / 简 | Same as zh-CN for now. |
Note: zh-TW and zh-HK are derived from zh-Hant. zh-CN is derived from zh-Hans. Currently, zh-MO shares the same dictionary as zh-HK, and zh-MY/zh-SG share the same dictionary as zh-CN, unless additional rules are provided.
Chained dictionary groups from OpenCC are flattened and merged with the MediaWiki conversion table for each target variant, then compiled into an Aho-Corasick automaton at compile-time. After internal compression, the bundled conversion tables and automata occupy ~0.6 MiB (with MediWiki enabled only) or ~2.7 MiB (with both MediaWiki and OpenCC enabled).
Performance
Even with all rulesets enabled, zhconv-rs remains faster than most alternatives. Comparative benchmarks against other crates live in bench-compare/ (requires OpenCC ≤ 1.2). cargo bench base --features bench,mediawiki,opencc benchmarks zhconv alone.
Conversion runs in a single pass in O(n+m) linear time by default, where n is the length of the input text and m is the maximum length of source word in conversion tables, regardless of which rulesets are enabled. When converting wikitext containing MediaWiki conversion rules, the time complexity may degrade to O(n*m) in the worst case, if the corresponding function or flag is explicitly chosen.
On a typical modern PC, prebuilt converters load in a few milliseconds with default features (~2–5 ms). Enabling the optional opencc feature increases load time (typically 20–25 ms per target). Throughput generally ranges from 100–200 MB/s.
cargo bench base --features bench on AMD EPYC 7B13 (GitPod) by v0.3:
Using conversion tables sourced from MediaWiki by default
load/zh2Hant time: [4.6368 ms 4.6862 ms 4.7595 ms]
load/zh2Hans time: [2.2670 ms 2.2891 ms 2.3138 ms]
load/zh2TW time: [4.7115 ms 4.7543 ms 4.8001 ms]
load/zh2HK time: [5.4438 ms 5.5474 ms 5.6573 ms]
load/zh2MO time: [4.9503 ms 4.9673 ms 4.9850 ms]
load/zh2CN time: [3.0809 ms 3.1046 ms 3.1323 ms]
load/zh2SG time: [3.0543 ms 3.0637 ms 3.0737 ms]
load/zh2MY time: [3.0514 ms 3.0640 ms 3.0787 ms]
zh2CN wikitext basic time: [385.95 µs 388.53 µs 391.39 µs]
zh2TW wikitext basic time: [393.70 µs 395.16 µs 396.89 µs]
zh2TW wikitext extended time: [1.5105 ms 1.5186 ms 1.5271 ms]
zh2CN 天乾物燥 time: [46.970 ns 47.312 ns 47.721 ns]
zh2TW data54k time: [200.72 µs 201.54 µs 202.41 µs]
zh2CN data54k time: [231.55 µs 232.86 µs 234.30 µs]
zh2Hant data689k time: [2.0330 ms 2.0513 ms 2.0745 ms]
zh2TW data689k time: [1.9710 ms 1.9790 ms 1.9881 ms]
zh2Hant data3185k time: [15.199 ms 15.260 ms 15.332 ms]
zh2TW data3185k time: [15.346 ms 15.464 ms 15.629 ms]
zh2TW data55m time: [329.54 ms 330.53 ms 331.58 ms]
is_hans data55k time: [404.73 µs 407.11 µs 409.59 µs]
infer_variant data55k time: [1.0468 ms 1.0515 ms 1.0570 ms]
is_hans data3185k time: [22.442 ms 22.589 ms 22.757 ms]
infer_variant data3185k time: [60.205 ms 60.412 ms 60.627 ms]
Using conversion tables derived from OpenCC additionally (`--features opencc`)
load/zh2Hant time: [22.074 ms 22.338 ms 22.624 ms]
load/zh2Hans time: [2.7913 ms 2.8126 ms 2.8355 ms]
load/zh2TW time: [23.068 ms 23.286 ms 23.520 ms]
load/zh2HK time: [23.358 ms 23.630 ms 23.929 ms]
load/zh2MO time: [23.363 ms 23.627 ms 23.913 ms]
load/zh2CN time: [3.6778 ms 3.7222 ms 3.7722 ms]
load/zh2SG time: [3.6522 ms 3.6848 ms 3.7202 ms]
load/zh2MY time: [3.6642 ms 3.7079 ms 3.7545 ms]
zh2CN wikitext basic time: [396.17 µs 402.51 µs 409.36 µs]
zh2TW wikitext basic time: [442.16 µs 447.53 µs 453.27 µs]
zh2TW wikitext extended time: [1.5795 ms 1.6007 ms 1.6233 ms]
zh2CN 天乾物燥 time: [47.884 ns 48.878 ns 49.953 ns]
zh2TW data54k time: [255.25 µs 259.01 µs 262.92 µs]
zh2CN data54k time: [233.74 µs 236.99 µs 240.67 µs]
zh2Hant data689k time: [3.9696 ms 4.0005 ms 4.0327 ms]
zh2TW data689k time: [3.4593 ms 3.4896 ms 3.5203 ms]
zh2Hant data3185k time: [27.710 ms 27.955 ms 28.206 ms]
zh2TW data3185k time: [30.298 ms 30.858 ms 31.428 ms]
zh2TW data55m time: [500.95 ms 515.80 ms 531.34 ms]
is_hans data55k time: [461.22 µs 470.99 µs 481.20 µs]
infer_variant data55k time: [1.1669 ms 1.1759 ms 1.1852 ms]
is_hans data3185k time: [26.609 ms 26.964 ms 27.385 ms]
infer_variant data3185k time: [74.878 ms 76.262 ms 77.818 ms]
Limitations
Accuracy
Rule-based converters cannot capture every possible linguistic nuance. Like most others, the implementation employs a leftmost-longest matching strategy (a.k.a forward maximum matching), prioritizing to the earliest and longest matches in the text. For example, if a ruleset contains both 干 → 幹, 天干 → 天干, and 天干物燥 → 天乾物燥, the converter will prefer the longer match 天乾物燥, since it appears earlier and spans more characters. This generally works well but may cause occasional mis-conversions.
Wikitext support
The implementation supports most MediaWiki conversion syntax, while not fully compliant with the original MediaWiki implementation.
Since rebuilding automata dynamically is impractical, rules (e.g., -{H|zh-hans:鹿|zh-hant:马}- in MediaWiki syntax) in text are extracted in a first pass, a temporary automaton is constructed, and the text is converted in a second pass. The time complexity may degrade to O(n*m) in the worst case, where n is the input text length and m is the maximum length of source words in dictionaries, which is equivalent to a brute-force approach.
License
The library itself is licensed under MIT OR Apache-2.0, at the licensee’s option. BUT it may bundle:
- Conversion tables from MediaWiki (the default, gated by the feature
mediawiki) which are licensed under GPL-2.0-or-later. - Dictionaries from OpenCC (gated by the feature
opencc) licensed under Apache-2.0.
For MIT compatibility, disable the default mediawiki feature and enable opencc (with optional compress, recommended for reducing binary size) to use prebuilt converters and tables.
Credits
Rulesets: MediaWiki and OpenCC.
Fast double-array Aho-Corasick automata implementation in Rust: daachorse
References & related implementations:
- https://github.com/gumblex/zhconv : Python implementation of
zhConver{ter,sion}.php. - https://github.com/BYVoid/OpenCC/ : Widely adopted Chinese converter.
- https://zh.wikipedia.org/wiki/Wikipedia:字詞轉換處理
- https://zh.wikipedia.org/wiki/Help:高级字词转换语法
- https://github.com/wikimedia/mediawiki/blob/master/includes/language/LanguageConverter.php
Metadata
Release files for zhconv-rs 0.4.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| zhconv_rs-0.4.2.tar.gz | 6.6 MB | Details |
Built distributions (wheels)
Total release size: 25.4 MB
Release files / zhconv_rs-0.4.2.tar.gz
| Download URL | zhconv_rs-0.4.2.tar.gz |
|---|---|
| Size | 6.6 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
c1efa15dfecfbbb5cf0e7d2a0be04b62e2a7aeae434fc09844dd537304d3baad
|
|
BLAKE2b-256 checksum How to use checksums |
04f0a17913c86954afb60d5cb16a64ef9c621e658989eff3549fc49e565a050f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
maturin/1.15.0
|
Release files / zhconv_rs-0.4.2-cp39-abi3-win_amd64.whl
| Download URL | zhconv_rs-0.4.2-cp39-abi3-win_amd64.whl |
|---|---|
| Size | 1.2 MB |
| Tags | CPython 3.9 Windows x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
f058997de8d629b8846901e08d51394e4d73ebce30cfb07c96b483a96b671b99
|
|
BLAKE2b-256 checksum How to use checksums |
3ded49c3c32b14ca3d4c5e0c613509d0bf07a81331436397916a0edda6881311
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
maturin/1.15.0
|
Release files / zhconv_rs-0.4.2-cp39-abi3-win32.whl
| Download URL | zhconv_rs-0.4.2-cp39-abi3-win32.whl |
|---|---|
| Size | 1.2 MB |
| Tags | CPython 3.9 Windows x86-32 abi3 |
|
SHA-256 checksum How to use checksums |
e5c73eb9a98877352f11cfa54c52c977e9f9fc56c5a965c33a1a2c0efdfde2c1
|
|
BLAKE2b-256 checksum How to use checksums |
d9d7ac6cfdaaa2022db83029b28eb2883565260a13a573eb6c108ab3739cd9ba
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
maturin/1.15.0
|
Release files / zhconv_rs-0.4.2-cp39-abi3-musllinux_1_2_x86_64.whl
| Download URL | zhconv_rs-0.4.2-cp39-abi3-musllinux_1_2_x86_64.whl |
|---|---|
| Size | 1.5 MB |
| Tags | CPython 3.9 Linux musl 1.2+ x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
5511fcbe1b19a5c3b7af22df38c342eb1a8a86a0ffcbd57cba6f94b0aa4efd3f
|
|
BLAKE2b-256 checksum How to use checksums |
c6fbd83800053a914a8e783b6403faa6a393b0bd83de4548621d1f17e01fa49a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
maturin/1.15.0
|
Release files / zhconv_rs-0.4.2-cp39-abi3-musllinux_1_2_i686.whl
| Download URL | zhconv_rs-0.4.2-cp39-abi3-musllinux_1_2_i686.whl |
|---|---|
| Size | 1.5 MB |
| Tags | CPython 3.9 Linux musl 1.2+ x86-32 abi3 |
|
SHA-256 checksum How to use checksums |
d7bc9d665c18d7590dd14d2afccac2e8e8cc2082192acab879fb63b719441609
|
|
BLAKE2b-256 checksum How to use checksums |
74444be5cca2e6c26c2f7cad8d9ef0a5d01d0cffe69d78b35bdcd5cc298b5148
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
maturin/1.15.0
|
Release files / zhconv_rs-0.4.2-cp39-abi3-musllinux_1_2_armv7l.whl
| Download URL | zhconv_rs-0.4.2-cp39-abi3-musllinux_1_2_armv7l.whl |
|---|---|
| Size | 1.5 MB |
| Tags | CPython 3.9 Linux musl 1.2+ ARMv7l abi3 |
|
SHA-256 checksum How to use checksums |
a6984d90f4d25efd97aeacf1015373961a404b674df2798044ab7c7ebcca70aa
|
|
BLAKE2b-256 checksum How to use checksums |
32727a810bad1d2aa79fe5904e5d52b9f6fd2ffa59202a1851cfcf80cff1a7af
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
maturin/1.15.0
|
Release files / zhconv_rs-0.4.2-cp39-abi3-musllinux_1_2_aarch64.whl
| Download URL | zhconv_rs-0.4.2-cp39-abi3-musllinux_1_2_aarch64.whl |
|---|---|
| Size | 1.4 MB |
| Tags | CPython 3.9 Linux musl 1.2+ ARM64 abi3 |
|
SHA-256 checksum How to use checksums |
c6f1665df8d50ae712e2f5c4944cdd7a9560fbb5dcc473e379d3c013cb4d280d
|
|
BLAKE2b-256 checksum How to use checksums |
89849a706d738a0cbb33be7bc86d16ac7bdc42baf3701be9c036b4cde55efdf7
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
maturin/1.15.0
|
Release files / zhconv_rs-0.4.2-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
| Download URL | zhconv_rs-0.4.2-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl |
|---|---|
| Size | 1.3 MB |
| Tags | CPython 3.9 Linux glibc 2.17+ x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
b8f848fe71c17cf8db8c2fd5c24adb129ae581845ad77be259863eff0adbb387
|
|
BLAKE2b-256 checksum How to use checksums |
ad9438541c41a8450edba382670308df0916a4baee665ef50b19fefe6b209d3e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
maturin/1.15.0
|
Release files / zhconv_rs-0.4.2-cp39-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl
| Download URL | zhconv_rs-0.4.2-cp39-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl |
|---|---|
| Size | 1.4 MB |
| Tags | CPython 3.9 Linux glibc 2.17+ IBM System/390x abi3 |
|
SHA-256 checksum How to use checksums |
6b51f857f62825839aa3c5d449f26992ae47005c3e16ebec911ae98ebb869633
|
|
BLAKE2b-256 checksum How to use checksums |
0732e1c99934a663cd0aa2cfbe67a229eb28ef0f9ae0700432d7a94414814596
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
maturin/1.15.0
|
Release files / zhconv_rs-0.4.2-cp39-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl
| Download URL | zhconv_rs-0.4.2-cp39-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl |
|---|---|
| Size | 1.4 MB |
| Tags | CPython 3.9 Linux glibc 2.17+ PowerPC 64-le abi3 |
|
SHA-256 checksum How to use checksums |
abe2ee7f0ef0f259affa4d7c9e1167541187c52649187679d881700e4bcea1c9
|
|
BLAKE2b-256 checksum How to use checksums |
fddde24373473206316794c4cf8d31fa98d88f638173e56819d1156bd05a2614
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
maturin/1.15.0
|
Release files / zhconv_rs-0.4.2-cp39-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
| Download URL | zhconv_rs-0.4.2-cp39-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl |
|---|---|
| Size | 1.2 MB |
| Tags | CPython 3.9 Linux glibc 2.17+ ARMv7l abi3 |
|
SHA-256 checksum How to use checksums |
4c9efd56720a6c4a647492fc3ef61266fd1f369de73dde02f021b7a6baa56d1c
|
|
BLAKE2b-256 checksum How to use checksums |
5920a078094ce470f1c0c4b09fbc3ae2fccd0f806d4d279c913767efda621de6
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
maturin/1.15.0
|
Release files / zhconv_rs-0.4.2-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
| Download URL | zhconv_rs-0.4.2-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl |
|---|---|
| Size | 1.3 MB |
| Tags | CPython 3.9 Linux glibc 2.17+ ARM64 abi3 |
|
SHA-256 checksum How to use checksums |
415a06249539ed8cab086c62e2c7f6b4f6d370dec66165cab5039c72bf67a678
|
|
BLAKE2b-256 checksum How to use checksums |
f5834c436763fe17fb8ce6b0f52dc95258b73d427334b55a79467718799999c8
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
maturin/1.15.0
|
Release files / zhconv_rs-0.4.2-cp39-abi3-manylinux_2_5_i686.manylinux1_i686.whl
| Download URL | zhconv_rs-0.4.2-cp39-abi3-manylinux_2_5_i686.manylinux1_i686.whl |
|---|---|
| Size | 1.3 MB |
| Tags | CPython 3.9 Linux glibc 2.5+ x86-32 abi3 |
|
SHA-256 checksum How to use checksums |
db5c708ce6cac366a10598fe5499b1e950bd0378db023551c669cf9dd43fe40e
|
|
BLAKE2b-256 checksum How to use checksums |
66ae4bc55a18c2af65058a951890dfe9f19039a0cb9f7d8a2aa08243e9d18a99
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
maturin/1.15.0
|
Release files / zhconv_rs-0.4.2-cp39-abi3-macosx_11_0_arm64.whl
| Download URL | zhconv_rs-0.4.2-cp39-abi3-macosx_11_0_arm64.whl |
|---|---|
| Size | 1.2 MB |
| Tags | CPython 3.9 abi3 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
a037e051c4f60d1d125e2b967c97e6a757bcd07c0ce09d8f1c3bd99e590c8f74
|
|
BLAKE2b-256 checksum How to use checksums |
a1274565778000bd688e97d6d9675d17b14eb387779e97e518cdb572b2569838
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
maturin/1.15.0
|
Release files / zhconv_rs-0.4.2-cp39-abi3-macosx_10_12_x86_64.whl
| Download URL | zhconv_rs-0.4.2-cp39-abi3-macosx_10_12_x86_64.whl |
|---|---|
| Size | 1.3 MB |
| Tags | CPython 3.9 abi3 macOS 10.12+ x86-64 |
|
SHA-256 checksum How to use checksums |
dcc5d4b877bed51898c645a5b515815c84d923e95ac692b597e0fcd171d96775
|
|
BLAKE2b-256 checksum How to use checksums |
ec0d48d99dbda4eba647e61e2d7bb4987c96c87c53ad4f107a4b3c63b88dc566
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
maturin/1.15.0
|