#pattern #string #multi #string-search #search-pattern #deserialize #search

matcher_rs

一个高性能匹配器,用于解决词匹配中的逻辑和文本变化问题,采用Rust实现

36个版本 (4个破坏性版本)

0.5.4 2024年8月23日
0.5.3 2024年7月26日
0.4.6 2024年7月15日
0.3.4 2024年6月27日
0.1.9 2024年6月12日

#376 in 文本处理

Download history 693/week @ 2024-06-07 988/week @ 2024-06-14 831/week @ 2024-06-21 193/week @ 2024-06-28 531/week @ 2024-07-05 446/week @ 2024-07-12 210/week @ 2024-07-19 427/week @ 2024-07-26 30/week @ 2024-08-02

每月825次下载
用于 2 crates

Apache-2.0 OR MIT

285KB
2.5K SLoC

匹配器

一个高性能匹配器,用于解决词匹配中的 逻辑和文本变化 问题,采用Rust实现。

有关详细实现,请参阅设计文档

功能

  • 多种匹配方法:
    • 简单词匹配
    • 基于正则表达式的匹配
    • 基于相似度的匹配
  • 文本转换:
    • 简拼:将传统汉字简化为简体字。示例:蟲艸 -> 虫艹
    • 删除:删除特定字符。示例:*Fu&*iii&^%%*&kkkk -> Fuiiikkkk
    • 规范化:将特殊字符规范化为可识别的字符。示例:𝜢𝕰𝕃𝙻𝝧 𝙒ⓞᵣℒ𝒟! -> hello world!
    • 拼音:将汉字转换为拼音进行模糊匹配。示例:西安 -> xi an,匹配 洗按 -> xi an,但不匹配 -> xian
    • 拼音字符:将汉字转换为拼音。示例:西安 -> xian,匹配 洗按 -> xian
  • AND OR NOT 词匹配:
    • 考虑词重复的次数。
    • 示例:hello&world 匹配 hello worldworld,hello
    • 示例:&&& 匹配 无无法天(因为 重复两次),但不匹配 无法天
    • 示例:hello~helloo~hhello 匹配 hello,但不匹配 helloohhello
  • 自定义豁免列表:排除特定单词以进行匹配。
  • 高效处理大型单词列表:针对性能优化。

使用方法

添加到您的项目

要在您的 Rust 项目中使用 matcher_rs,请运行以下命令

cargo add matcher_rs

配置说明

  • Matcher 的配置由 MatchTableMap = HashMap<u32, Vec<MatchTable>> 类型定义,MatchTableMap 的键称为 match_id对于每个 match_id,内部必须有一个唯一的 table_id
  • SimpleMatcher 的配置由 SimpleTable = HashMap<ProcessType, HashMap<u32, &str>> 类型定义,值 HashMap<u32, &str> 的键称为 word_idword_id 必须是全局唯一的

匹配表

  • table_id:匹配表的唯一 ID。
  • match_table_type:匹配表类型。
  • word_list:匹配表的单词列表。
  • exemption_process_type:豁免简单匹配的类型。
  • exemption_word_list:匹配表的豁免单词列表。

对于每个匹配表,在 word_list 上执行单词匹配,在 exemption_word_list 上执行豁免单词匹配。如果豁免单词匹配结果为 True,则单词匹配结果将为 False。

匹配表类型

  • Simple:支持由 process_type 定义的文本规范定义的简单多模式匹配。
    • 它可以处理组合模式和重复次数敏感匹配,由 &~ 分隔,例如 hello&world&hello 将匹配 hellohelloworldworldhellohello,但由于 hello 的重复次数,不匹配 helloworld
  • Regex:支持正则表达式模式匹配。
    • SimilarChar:支持使用正则表达式进行相似字符匹配。
      • ["hello,hallo,hollo,hi", "word,world,wrd,🌍", "!,?,~"] 将匹配 helloworld!hollowrd?hi🌍~ ··· 列表中通过 , 分隔的单词的任何组合。
    • Acrostic:支持使用正则表达式进行首字母匹配(目前仅支持中文和简单英语句子)。
      • ["h,e,l,l,o", "你,好"] 将匹配 希望, 持久, 爱情, 持续, 前进.你的笑容温暖, 好心情常伴。
    • Regex:支持正则表达式匹配。
      • ["h[aeiou]llo", "w[aeiou]rd"] 将匹配 helloworldhillowurld ··· 任何匹配列表中正则表达式的文本。
  • Similar:支持基于距离和阈值的相似文本匹配。
    • Levenshtein:支持基于Levenshtein距离的相似文本匹配。

ProcessType

  • None:无转换。
  • Fanjian:繁体中文转简体中文转换。基于 FANJIAN
    • 妳好 -> 你好
    • 現⾝ -> 现身
  • Delete:删除所有标点符号、特殊字符和空白。基于 TEXT_DELETEWHITE_SPACE
    • hello, world! -> helloworld
    • 《你∷好》 -> 你好
  • Normalize:将所有英文字符和数字变体归一化到基本字符。基于 NORMNUM_NORM
    • ℋЀ⒈㈠Õ -> he11o
    • ⒈Ƨ㊂ -> 123
  • PinYin:将所有Unicode中文字符转换为带边界的拼音。基于 PINYIN
    • 你好 -> ni hao
    • 西安 -> xi an
  • PinYinChar:将所有Unicode中文字符转换为不带边界的拼音。基于 PINYIN
    • 你好 -> nihao
    • 西安 -> xian

您可以根据需要组合这些转换。为了方便,还提供了预定义的组合,如 DeleteNormalizeFanjianDeleteNormalize

由于 PinYinPinYinChar 的一个更有限的版本,因此请避免将 PinYinPinYinChar 组合。在某些情况下,如 xian,可以被视为两个词 xian,或者是一个词 xian

基本示例

以下是一个使用 Matcher 结构进行文本匹配的基本示例

use matcher_rs::{text_process, reduce_text_process, ProcessType};

let result = text_process(ProcessType::Delete, "你好,世界!");
let result = reduce_text_process(ProcessType::FanjianDeleteNormalize, "你好,世界!");
use std::collections::HashMap;
use matcher_rs::{Matcher, MatchTableMap, MatchTable, MatchTableType, ProcessType};

let match_table_map: MatchTableMap = HashMap::from_iter(vec![
    (1, vec![MatchTable {
        table_id: 1,
        match_table_type: MatchTableType::Simple { process_type: ProcessType::FanjianDeleteNormalize},
        word_list: vec!["example", "test"],
        exemption_process_type: ProcessType::None,
        exemption_word_list: vec![],
    }]),
]);
let matcher = Matcher::new(&match_table_map);
let text = "This is an example text.";
let results = matcher.word_match(text);
use std::collections::HashMap;
use matcher_rs::{ProcessType, SimpleMatcher};

let mut simple_table = HashMap::new();
let mut simple_word_map = HashMap::new();

simple_word_map.insert(1, "你好");
simple_word_map.insert(2, "世界");

simple_table.insert(ProcessType::Fanjian, simple_word_map);

let matcher = SimpleMatcher::new(&simple_table);
let text = "你好,世界!";
let results = matcher.process(text);

有关更详细的用法示例,请参阅 test.rs 文件。

特性标志

  • runtime_build:启用 runtime_build 特性后,我们可以在运行时构建 matcher 进程,但会增加构建时间。
  • serde:启用 serde 特性后,我们可以序列化和反序列化 matcher 和 simple_matcher。由于我不知道如何正确地序列化它,当模式大小较小时(例如,小于100),这将导致性能下降。
  • dfa:启用 dfa 特性后,我们可以使用 dfa 进行简单匹配,但会显著增加内存消耗。

默认特性是 dfa。如果您想使 MatcherSimpleMatcher 可序列化,您应该启用 serde 特性。

基准测试

基准测试对以下对进行基准测试(CN_WORD_LIST_100000CN_HAYSTACK)和(EN_WORD_LIST_100000EN_HAYSTACK)。单词选择完全是随机的。

matcher_rs 库包含用于测量 matcher 性能的基准测试。您可以在 bench.rs 文件中找到基准测试。要运行基准测试,请使用以下命令

cargo bench
Current default simple match type: ProcessType(None)
Current default simple word map size: 1000
Current default combined times: 2
Timer precision: 41 ns
bench                                     fastest       │ slowest       │ median        │ mean          │ samples │ iters
├─ build_cn                                             │               │               │               │         │
│  ├─ build_cn_by_combined_times                        │               │               │               │         │
│  │  ├─ 1                                2.5 ms        │ 9.171 ms      │ 2.621 ms      │ 2.975 ms      │ 100100
│  │  ├─ 2                                5.088 ms      │ 6.116 ms      │ 5.407 ms      │ 5.447 ms      │ 100100
│  │  ├─ 3                                7.761 ms      │ 8.842 ms      │ 7.904 ms      │ 7.954 ms      │ 100100
│  │  ├─ 4                                10.27 ms      │ 12.08 ms      │ 10.86 ms      │ 10.87 ms      │ 100100
│  │  ╰─ 5                                12.83 ms      │ 13.96 ms      │ 13.27 ms      │ 13.34 ms      │ 100100
│  ├─ build_cn_by_multiple_process_type   25.63 ms      │ 49.57 ms      │ 26.19 ms      │ 27.25 ms      │ 100100
│  ├─ build_cn_by_process_type                          │               │               │               │         │
│  │  ├─ "delete"                         5.162 ms      │ 6.166 ms      │ 5.458 ms      │ 5.521 ms      │ 100100
│  │  ├─ "delete_normalize"               5.359 ms      │ 6.164 ms      │ 5.599 ms      │ 5.7 ms        │ 100100
│  │  ├─ "fanjian"                        5.18 ms       │ 18.05 ms      │ 5.364 ms      │ 5.686 ms      │ 100100
│  │  ├─ "fanjian_delete_normalize"       5.342 ms      │ 5.605 ms      │ 5.413 ms      │ 5.427 ms      │ 100100
│  │  ├─ "none"                           5.206 ms      │ 6.014 ms      │ 5.404 ms      │ 5.466 ms      │ 100100
│  │  ├─ "normalize"                      5.136 ms      │ 6.022 ms      │ 5.313 ms      │ 5.413 ms      │ 100100
│  │  ├─ "pinyin"                         7.15 ms       │ 10.4 ms       │ 7.749 ms      │ 7.776 ms      │ 100100
│  │  ╰─ "pinyinchar"                     6.56 ms       │ 8.648 ms      │ 6.875 ms      │ 6.9 ms        │ 100100
│  ╰─ build_cn_by_simple_word_map_size                  │               │               │               │         │
│     ├─ 100                              462.1 µs      │ 640.2 µs      │ 497.6 µs      │ 503.9 µs      │ 100100
│     ├─ 1000                             5.205 ms      │ 6.055 ms      │ 5.444 ms      │ 5.511 ms      │ 100100
│     ├─ 10000                            49.3 ms       │ 75.97 ms      │ 51.22 ms      │ 51.94 ms      │ 9797
│     ╰─ 50000                            185.7 ms      │ 207.6 ms      │ 194.1 ms      │ 194.3 ms      │ 2626
├─ build_en                                             │               │               │               │         │
│  ├─ build_en_by_combined_times                        │               │               │               │         │
│  │  ├─ 1                                5.982 ms      │ 7.846 ms      │ 6.418 ms      │ 6.451 ms      │ 100100
│  │  ├─ 2                                12.64 ms      │ 14.05 ms      │ 13.41 ms      │ 13.37 ms      │ 100100
│  │  ├─ 3                                20.83 ms      │ 72.35 ms      │ 21.57 ms      │ 23.43 ms      │ 100100
│  │  ├─ 4                                28.75 ms      │ 31.95 ms      │ 29.36 ms      │ 29.54 ms      │ 100100
│  │  ╰─ 5                                37.31 ms      │ 62.69 ms      │ 37.61 ms      │ 38.02 ms      │ 100100
│  ├─ build_en_by_multiple_process_type   15.42 ms      │ 29.2 ms       │ 16.09 ms      │ 16.42 ms      │ 100100
│  ├─ build_en_by_process_type                          │               │               │               │         │
│  │  ├─ "delete"                         12.93 ms      │ 14.65 ms      │ 13.55 ms      │ 13.59 ms      │ 100100
│  │  ├─ "delete_normalize"               11.15 ms      │ 12.97 ms      │ 11.31 ms      │ 11.38 ms      │ 100100
│  │  ├─ "none"                           12.94 ms      │ 14.11 ms      │ 13.49 ms      │ 13.51 ms      │ 100100
│  │  ╰─ "normalize"                      11.36 ms      │ 12.83 ms      │ 12.15 ms      │ 12.11 ms      │ 100100
│  ╰─ build_en_by_simple_word_map_size                  │               │               │               │         │
│     ├─ 100                              901.1 µs      │ 1.268 ms      │ 977.2 µs      │ 1.004 ms      │ 100100
│     ├─ 1000                             12.13 ms      │ 32.91 ms      │ 12.91 ms      │ 13.15 ms      │ 100100
│     ├─ 10000                            159.3 ms      │ 193 ms        │ 165 ms        │ 166.5 ms      │ 3131
│     ╰─ 50000                            712 ms        │ 857.7 ms      │ 716.7 ms      │ 739.5 ms      │ 77
├─ search_cn                                            │               │               │               │         │
│  ├─ search_cn_baseline                                │               │               │               │         │
│  │  ├─ 100                              2.927 ms      │ 4.723 ms      │ 3.239 ms      │ 3.251 ms      │ 100100
│  │  ├─ 1000                             3.084 ms      │ 3.915 ms      │ 3.406 ms      │ 3.426 ms      │ 100100
│  │  ├─ 10000                            8.098 ms      │ 9.623 ms      │ 8.314 ms      │ 8.372 ms      │ 100100
│  │  ╰─ 50000                            27.34 ms      │ 40.26 ms      │ 29.6 ms       │ 30.57 ms      │ 100100
│  ├─ search_cn_by_combined_times                       │               │               │               │         │
│  │  ├─ 1                                4 ms          │ 4.618 ms      │ 4.304 ms      │ 4.296 ms      │ 100100
│  │  ├─ 2                                5.097 ms      │ 5.676 ms      │ 5.446 ms      │ 5.422 ms      │ 100100
│  │  ├─ 3                                6.164 ms      │ 6.73 ms       │ 6.192 ms      │ 6.29 ms       │ 100100
│  │  ├─ 4                                6.948 ms      │ 8.172 ms      │ 7.438 ms      │ 7.314 ms      │ 100100
│  │  ╰─ 5                                9.285 ms      │ 9.946 ms      │ 9.777 ms      │ 9.766 ms      │ 100100
│  ├─ search_cn_by_multiple_process_type  61.99 ms      │ 94.96 ms      │ 65.04 ms      │ 65.7 ms       │ 100100
│  ├─ search_cn_by_process_type                         │               │               │               │         │
│  │  ├─ "delete"                         14.19 ms      │ 15.32 ms      │ 15.19 ms      │ 14.95 ms      │ 100100
│  │  ├─ "delete_normalize"               21.86 ms      │ 26.01 ms      │ 21.91 ms      │ 21.99 ms      │ 100100
│  │  ├─ "fanjian"                        7.295 ms      │ 7.861 ms      │ 7.337 ms      │ 7.372 ms      │ 100100
│  │  ├─ "fanjian_delete_normalize"       23.07 ms      │ 25.89 ms      │ 24.36 ms      │ 24.27 ms      │ 100100
│  │  ├─ "none"                           5.173 ms      │ 5.502 ms      │ 5.207 ms      │ 5.214 ms      │ 100100
│  │  ├─ "normalize"                      14.36 ms      │ 15.34 ms      │ 14.48 ms      │ 14.49 ms      │ 100100
│  │  ├─ "pinyin"                         42.33 ms      │ 43.75 ms      │ 42.43 ms      │ 42.46 ms      │ 100100
│  │  ╰─ "pinyinchar"                     42.16 ms      │ 43.93 ms      │ 42.32 ms      │ 42.38 ms      │ 100100
│  ╰─ search_cn_by_simple_word_map_size                 │               │               │               │         │
│     ├─ 100                              3.002 ms      │ 3.243 ms      │ 3.017 ms      │ 3.026 ms      │ 100100
│     ├─ 1000                             5.248 ms      │ 5.677 ms      │ 5.421 ms      │ 5.426 ms      │ 100100
│     ├─ 10000                            15.51 ms      │ 18.43 ms      │ 15.7 ms       │ 15.79 ms      │ 100100
│     ╰─ 50000                            52.89 ms      │ 64.13 ms      │ 55.85 ms      │ 55.99 ms      │ 9090
├─ search_en                                            │               │               │               │         │
│  ├─ search_en_baseline                                │               │               │               │         │
│  │  ├─ 100                              350.2 µs      │ 547.6 µs      │ 376.5 µs      │ 382.5 µs      │ 100100
│  │  ├─ 1000                             360.4 µs      │ 463.8 µs      │ 386 µs        │ 388.3 µs      │ 100100
│  │  ├─ 10000                            1.014 ms      │ 1.045 ms      │ 1.02 ms       │ 1.022 ms      │ 100100
│  │  ╰─ 50000                            1.015 ms      │ 1.051 ms      │ 1.02 ms       │ 1.021 ms      │ 100100
│  ├─ search_en_by_combined_times                       │               │               │               │         │
│  │  ├─ 1                                1.787 ms      │ 2.475 ms      │ 1.808 ms      │ 1.831 ms      │ 100100
│  │  ├─ 2                                2.519 ms      │ 2.772 ms      │ 2.528 ms      │ 2.535 ms      │ 100100
│  │  ├─ 3                                2.58 ms       │ 2.926 ms      │ 2.6 ms        │ 2.609 ms      │ 100100
│  │  ├─ 4                                2.816 ms      │ 3.299 ms      │ 2.827 ms      │ 2.837 ms      │ 100100
│  │  ╰─ 5                                2.753 ms      │ 3.387 ms      │ 2.768 ms      │ 2.778 ms      │ 100100
│  ├─ search_en_by_multiple_process_type  10.65 ms      │ 11.94 ms      │ 10.68 ms      │ 10.72 ms      │ 100100
│  ├─ search_en_by_process_type                         │               │               │               │         │
│  │  ├─ "delete"                         7.012 ms      │ 7.4 ms        │ 7.106 ms      │ 7.112 ms      │ 100100
│  │  ├─ "delete_normalize"               8.678 ms      │ 9.234 ms      │ 8.787 ms      │ 8.785 ms      │ 100100
│  │  ├─ "none"                           2.085 ms      │ 2.373 ms      │ 2.222 ms      │ 2.223 ms      │ 100100
│  │  ╰─ "normalize"                      3.919 ms      │ 4.235 ms      │ 4.179 ms      │ 4.175 ms      │ 100100
│  ╰─ search_en_by_simple_word_map_size                 │               │               │               │         │
│     ├─ 100                              1.361 ms      │ 1.625 ms      │ 1.447 ms      │ 1.438 ms      │ 100100
│     ├─ 1000                             2.446 ms      │ 2.802 ms      │ 2.617 ms      │ 2.583 ms      │ 100100
│     ├─ 10000                            3.166 ms      │ 4.672 ms      │ 3.281 ms      │ 3.298 ms      │ 100100
│     ╰─ 50000                            5.981 ms      │ 8.647 ms      │ 6.054 ms      │ 6.101 ms      │ 100100
╰─ single_line                                          │               │               │               │         │
   ├─ search_cn_single_line                             │               │               │               │         │
   │  ├─ 100                              259.7 ns      │ 275.3 ns      │ 267.5 ns      │ 267.7 ns      │ 1001600
   │  ├─ 1000                             314.3 ns      │ 335.2 ns      │ 319.6 ns      │ 320.1 ns      │ 1001600
   │  ├─ 10000                            499.3 ns      │ 12.24 µs      │ 582.3 ns      │ 711.4 ns      │ 100100
   │  ╰─ 50000                            1.249 µs      │ 26.66 µs      │ 1.333 µs      │ 1.673 µs      │ 100100
   ╰─ search_en_single_line                             │               │               │               │         │
      ├─ 100                              56.28 ns      │ 61.17 ns      │ 56.93 ns      │ 57.85 ns      │ 10012800
      ├─ 1000                             60.18 ns      │ 61.82 ns      │ 60.84 ns      │ 60.74 ns      │ 10012800
      ├─ 10000                            332.3 ns      │ 5.249 µs      │ 416.3 ns      │ 477.6 ns      │ 100100
      ╰─ 50000                            457.3 ns      │ 15.2 µs       │ 540.3 ns      │ 706.8 ns      │ 100100

贡献

欢迎对 matcher_rs 的贡献!如果您发现了一个错误或有一个特性请求,请在该 GitHub 仓库上创建一个问题。如果您想贡献代码,请分叉仓库并提交一个 pull request。

许可协议

matcher_rs 在 MIT 或 Apache-2.0 许可协议下授权。

更多信息

有关更多详细信息,请访问 GitHub 仓库

依赖关系

~7–14MB
~162K SLoC