3个版本 (破坏性)
0.3.0 | 2024年7月3日 |
---|---|
0.2.0 | 2024年2月6日 |
0.1.0 | 2021年9月21日 |
655 在 文本处理 中
每月124次下载
32KB
519 行
Lexmatch
这是一个简单的词典匹配工具,给定一个单词或短语的词典,识别给定目标文本中的所有匹配项,并返回它们的精确位置。它可用于计算词典在目标语料库中的频率列表。
实现使用后缀数组或哈希表。文本必须是纯文本UTF-8。对于前者实现(默认),限制为2^32字节(约4GB)。对于后者实现(--tokens/
--cjk
),没有此类限制。输出的偏移量将是UTF-8 字节位置。
此工具仅进行精确(或大小写不敏感)匹配,如果您需要对词典进行模糊匹配,请查看analiticcl。
安装
您可以使用Rust的包管理器构建和安装最新稳定版本
cargo install lexmatch
或者如果您想克隆此仓库后使用开发版本
cargo install --path .
系统上还没有 cargo/rust?在基于 Debian/ubuntu 的系统上,请在 sudo apt install cargo
,在 macOS 上,请在 brew install rust
,或使用 rustup。
用法
请参阅 lexmatch --help
。
简单示例
$ lexmatch --lexicon lexicon.lst corpus.txt
词典必须是纯文本UTF-8,每行一个条目,条目不一定是单个单词,长度也不受限制。如果词典由制表符分隔值(TSV)组成,则仅考虑第一列,其余忽略。
除了词典外,您还可以使用 --query
在命令行上提供要查询的模式。
默认情况下,您将获得一个TSV文件,其中包含文本列、出现次数列以及每个匹配项的起始位置列(UTF-8字节位置,动态列)
$ lexmatch --query good --query bad /nettmp/republic.short.txt
Reading text from /tmp/republic.short.txt...
Building suffix array (this may take a while)...
Searching...
good 4 193 3307 3480 278
bad 3 201 3315 3488
默认情况下,匹配是区分大小写的,若要启用不区分大小写的匹配,请添加--no-case
(所有输入和输出将转换为小写,在极少数情况下可能导致UTF-8偏移量在原始文本中不再有效)。
对于详细输出,请添加--verbose
。这将产生更干净的TSV(制表符分隔值)输出,您可以轻松导入,例如在STAM工具中。
$ lexmatch --verbose --query good --query bad /nettmp/republic.short.txt
Text BeginUtf8Offset EndUtf8Offset
Reading text from /tmp/republic.short.txt...
Building suffix array (this may take a while)...
Searching...
good 193 197
good 3307 3311
good 3480 3484
good 278 282
bad 201 204
bad 3315 3318
bad 3488 3491
您可以提供多个词库以及多个测试文件,输出将输出词库和/或测试文件。如果多个词库匹配,它们都会返回(以分号分隔)。结果顺序是任意的。
如果您不关心精确的位置,而只想计算词库中每个项目的出现次数,或者通过--query
传递,请传递--count-only
。
$ lexmatch --count-only --query good --query bad /tmp/republic.short.txt
Reading text from /tmp/republic.short.txt...
Building suffix array (this may take a while)...
Searching...
good 4
bad 3
您可以使用--freq
配置最小频率阈值。
除了将整个词库与文本匹配之外,您还可以遍历文本中的标记,并检查它们是否出现在词库中。这使用哈希表而不是后缀数组,通常更快。然而,它更加有限,不能与频率阈值或计数一起使用。它将始终产生详细输出(类似于--verbose
)。
$ lexmatch --tokens --query good --query bad /nettmp/republic.short.txt
Text BeginUtf8Offset EndUtf8Offset
Reading text from /tmp/republic.short.txt...
good 193 197
bad 201 204
good 278 282
good 3307 3311
bad 3315 3318
good 3480 3484
bad 3488 3491
与之前不同,现在您会发现匹配项现在是按阅读顺序返回的。
如果您添加了--coverage
,那么您将获得一个包含一些覆盖率统计数据的额外最后一行。这有助于查看文本中有多少部分被您的词库所覆盖。
#coverage (tokens) = 7/627 = 0.011164274322169059
覆盖率也可以逐行计算,并针对多个词库进行匹配,我们还可以通过传递-
作为文件名来直接从stdin读取,而不是从文件读取。
$ echo "Is this good or bad?\nIt is quite good." | lexmatch --coverage-matrix --query good --query bad -
Reading text from -...
Line query
Is this good or bad? 0.4
It is quite good. 0.25
这可以作为简单的基于词库的语言检测方法。
$ echo "Do you know what language this is?\nUnd was ist das hier genau?\nÇa va assez bien je crois" | lexmatch -i --coverage-matrix --lexicon ~X/en.lst --lexicon ~X/de.lst --lexicon ~X/fr.lst -
Reading lexicon...
Reading lexicon...
Reading lexicon...
Reading text from -...
Line /home/proycon/exp/en.lst /home/proycon/exp/de.lst /home/proycon/exp/fr.lst Total
do you know what language this is? 1 0 0.14285714285714285 1.1428571428571428
und was ist das hier genau? 0.16666666666666666 0.8333333333333334 0.16666666666666666 1.1666666666666667
ça va assez bien je crois 0.2 0.2 0.6 1
当使用--tokens
(或--coverage-matrix
)时,我们依赖于空白和标点符号来分隔标记。这对于像中文、日文和韩文这样的没有这样分隔的语言不起作用。对于这些语言,可以通过传递--cjk
来达到类似的线性搜索行为,其中整数值表示要探索的最大字符长度。然后将执行贪婪搜索,优先考虑较长的模式而不是较短的模式。
依赖项
~1.5MB
~24K SLoC