Text

Chinese words

Chinese text split into words for search indexes and counts, with parts of speech, and written in pinyin with tones, tone numbers or initials for sorting and finding names.

Version 1.0.0 · 5 functions · 2 crates

#chinese#search#text#languages

Functions

What use chinese_segment.qwer gives a program, with the types Quillo sees. To take only some, or under other names: use chinese_cut, chinese_search_terms from chinese_segment (Quillo 0.6).

chinese_cut(text: str) → listor an error

The words of text, in order: "我来到北京清华大学" is ["我", "来到", "北京", "清华大学"]. Spaces and punctuation are left out; words in other scripts come through whole.

chinese_search_terms(text: str) → listor an error

The terms to index text under for search: its words and the shorter words inside long ones ("清华大学" gives "清华", "大学" and "清华大学" too), each once.

chinese_pinyin(text: str, style: str) → stror an error

text in pinyin, a syllable for each character, spaces between: style is "tone" ("zhōng guó"), "number" ("zhong1 guo2") or "plain" ("zhong guo"). Other characters stay as they are.

chinese_initials(text: str) → stror an error

The first letters of the pinyin of each Chinese character, in lower case: "张伟" is "zw", for finding contacts by their initials.

chinese_tag(text: str) → listor an error

The words of text with their part of speech, [{ word, tag }]: "n" noun, "v" verb, "ns" place name, "nr" person's name, "a" adjective... (the ICTCLAS tags).

Get it

$ quillo install chinese_segment               # chinese_segment.qwer into this folder$ quillo install chinese_segment --example     # and its example, chinese_segment.qwe

Or with curl:

$ curl -O https://quillolang.org/plugins/files/chinese_segment.qwer$ curl -O https://quillolang.org/plugins/files/chinese_segment.qwe

Then, in your program, all of it or only what you call:

main.qwe
use chinese_segment.qweruse chinese_cut, chinese_search_terms from chinese_segment      // Quillo 0.6: only these

It uses these crates, which cargo fetches the first time the plugin is built:

[dependencies]
jieba-rs = "0.11"pinyin = "0.11"

Example

chinese_segment.qwe
// A search index for Chinese product titles, and a contact list sorted and searched by pinyin.////   quillo run chinese_segment.qwe      then open http://localhost:8080/wordsuse "chinese_segment.qwer"route GET /words ? { text: str = "我来到北京清华大学" } = { words: chinese_cut(text)?, index: chinese_search_terms(text)?, tags: chinese_tag(text)? }let contacts = ["张伟", "王芳", "李娜", "刘洋"]route GET /contacts = contacts    | map((c) => { name: c, pinyin: chinese_pinyin(c, "tone")?, sort: chinese_pinyin(c, "plain")?, initials: chinese_initials(c)? })    | sort_by((c) => c.sort)route GET /pinyin ? { text: str } = { tone: chinese_pinyin(text, "tone")?, number: chinese_pinyin(text, "number")? }
$ quillo run chinese_segment.qwe$ curl 'localhost:8080/words'$ curl 'localhost:8080/contacts'

Source

chinese_segment.qwer
//! Chinese text split into words for search indexes and word counts (Chinese has no spaces), and written in pinyin, with tones or initials, for sorting and searching names.//! version: 1.0.0//!//! [dependencies]//! jieba-rs = "0.11"//! pinyin = "0.11"use jieba_rs::Jieba;use pinyin::ToPinyin;use serde_json::{json, Value};use std::sync::OnceLock;const MAX: usize = 1_000_000;fn jieba() -> &'static Jieba {    static J: OnceLock<Jieba> = OnceLock::new();    J.get_or_init(Jieba::new)}fn check(text: &str) -> Result<(), String> {    if text.len() > MAX { Err("text up to 1 MB".into()) } else { Ok(()) }}fn is_word(w: &str) -> bool {    w.chars().any(|c| c.is_alphanumeric())}/// The words of `text`, in order: "我来到北京清华大学" is ["我", "来到", "北京", "清华大学"]. Spaces and punctuation are left out; words in other scripts come through whole.pub fn chinese_cut(text: &str) -> Result<Vec<String>, String> {    check(text)?;    Ok(jieba().cut(text, true).into_iter().map(|t| t.word).filter(|w| is_word(w)).map(String::from).collect())}/// The terms to index `text` under for search: its words and the shorter words inside long ones ("清华大学" gives "清华", "大学" and "清华大学" too), each once.pub fn chinese_search_terms(text: &str) -> Result<Vec<String>, String> {    check(text)?;    let mut seen = std::collections::HashSet::new();    Ok(jieba().cut_for_search(text, true).into_iter().map(|t| t.word).filter(|w| is_word(w) && seen.insert(w.to_string())).map(String::from).collect())}/// `text` in pinyin, a syllable for each character, spaces between: `style` is "tone" ("zhōng guó"), "number" ("zhong1 guo2") or "plain" ("zhong guo"). Other characters stay as they are.pub fn chinese_pinyin(text: &str, style: &str) -> Result<String, String> {    check(text)?;    let mut parts: Vec<String> = Vec::new();    let mut other = String::new();    for (c, p) in text.chars().zip(text.to_pinyin()) {        match p {            Some(p) => {                if !other.trim().is_empty() {                    parts.push(other.trim().to_string());                }                other.clear();                parts.push(match style {                    "plain" => p.plain(),                    "number" => p.with_tone_num_end(),                    "tone" | "" => p.with_tone(),                    o => return Err(format!("style is \"tone\", \"number\" or \"plain\", not {:?}", o)),                }.to_string());            }            None => other.push(c),        }    }    if !other.trim().is_empty() {        parts.push(other.trim().to_string());    }    Ok(parts.join(" "))}/// The first letters of the pinyin of each Chinese character, in lower case: "张伟" is "zw", for finding contacts by their initials.pub fn chinese_initials(text: &str) -> Result<String, String> {    check(text)?;    Ok(text.to_pinyin().flatten().map(|p| p.first_letter()).collect())}/// The words of `text` with their part of speech, `[{ word, tag }]`: "n" noun, "v" verb, "ns" place name, "nr" person's name, "a" adjective... (the ICTCLAS tags).pub fn chinese_tag(text: &str) -> Result<Vec<Value>, String> {    check(text)?;    Ok(jieba().tag(text, true).into_iter().filter(|t| is_word(t.word)).map(|t| json!({ "word": t.word, "tag": t.tag })).collect())}
Thread
77Useful? Like it, or add to its thread below.

Thread 0 posts

On Chinese words: questions, tips, corrections, and code that uses it.

No posts yet. The first one opens the thread.