17 个版本
使用 Rust 2015 版
0.8.1 | 2017 年 3 月 4 日 |
---|---|
0.7.4 | 2016 年 10 月 25 日 |
0.7.1 | 2015 年 12 月 10 日 |
0.7.0 | 2015 年 11 月 12 日 |
0.6.2 | 2015 年 7 月 14 日 |
#1342 in 文本处理
162 每月下载量
用于 crowbook
84KB
1.5K SLoC
Caribon
用 Rust 编写的重复检测器。
演示服务器
如果您想了解 Caribon 的功能而不需要下载任何东西,可以查看这个运行 Caribon 作为网络服务的实例。
下载
可以使用 git
获取最新版本
$ git clone https://github.com/lise-henry/caribon.git
或者下载其中一个稳定(大致)的 版本。
(如果您只计划将 Caribon 作为您的 Rust 程序的库来使用,您不需要过于担心下载和构建,只需在您的 Cargo.toml
文件中添加 caribon = "*"
即可。)
构建
您需要 Rust 和 Cargo,请参阅它们的 安装说明。然后
$cargo build
应该可以完成工作,尽管您也可以直接运行 cargo build --release
。然后您可以运行 caribon,通过以下方式
$cargo run --发布
或者直接执行二进制文件(在 target/debug
或 target/release
中)
$target/release/caribon
安装
如果您有最新的 Cargo
版本,您可以使用
$cargo install caribon
(对于 crates.io 上的最新版本,或者
$cargo install --githttps://github.com/lise-henry/caribon
对于 GitHub 上的最新版本)
这将下载、构建和安装 Caribon。
Cargo 运行
如果您不想安装 Caribon,cargo run
可能是最简单的方法。请注意,但是,命令行参数必须以 --
开头,以便 cargo 将它们传递给二进制文件
$cargo run ----input=some_text.txt
此外,请注意,默认情况下,cargo run
会以调试模式构建和运行程序,这会比较慢。对于小文件来说这不是问题,但如果您计划检测小说中的重复内容,使用CPU密集型特性(例如模糊字符串匹配,见下文),则可能希望使用 --release
$ cargo run --release -- --input=big_file.html --output=output_big_file.html
示例
以下是一个 示例,展示了如何使用本README(之前版本)的HTML输出,通过以下命令获得
$caribon --语言=英语 --输入=README.html --输出=example.html --模糊=0.5
(注意,--fuzzy=0.5
,虽然有用,可以展示模糊字符串匹配确实可行,但不是一个明智的参数,因为它相当高(单词只需50%相似即可被视为相同,例如将 just
和 rust
匹配)。在实际应用中,建议使用更低的值。)
以下是一个 示例,显示终端中的 README.md
中的重复内容,使用以下命令
$caribon --语言=英语 --输入=README.md --模糊=0.5 | 更多
虽然将输出到终端对于小文件可能很有用,但HTML输出会提供更有用的结果,因为高亮显示一个单词将显示其其他出现位置。
选项
Caribon 提供了一系列选项。以下是其中一些选项的解释,从最常用到最复杂的
语言
--language=[english|french|spanish|...]
指定输入文件的语言。这很重要有两个原因。第一个原因是 Caribon 在内部使用一个词干库,它可以检测到从同一词干派生的单词,例如 "eats"、"eat" 和 "eating" 将被视为同一单词。有关此词干库如何工作的更多信息,请参阅 Snowball 项目网站。第二个原因是对于某些语言(目前仅为法语和英语),Caribon 提供了一个默认的单词列表,用于重复计数时忽略(例如,在英语中 "it"、"a" 等等都在其中)以避免结果文件杂乱。可以使用 "no_stemmer" 替代语言来禁用词干。这并不真的建议,但如果您想尝试在未实现的语言上使用 Caribon,则可能很有用。--list-languages
打印由词干库支持的语种列表。
输入和输出
--input=[file]
指定输入文件。默认情况下为stdin
,这意味着您需要直接输入文本,并以control-D
结束。如果file
是一个不存在的文件,则程序会终止。--output=[file]
指定输出文件。默认情况下为stdout
,将结果打印到终端。
输入和输出文件名的扩展名决定了输入和输出格式,例如,如果您传递 --input=text.html --output=result.html
,Caribon 将推断内容是 HTML,并且必须以 HTML 格式输出(因此 $ caribon < input.html > output.html
不等同于 $ caribon --input=input.html --output=output.html
:在前者的情况下,Caribon 将输入视为原始文本,并以 终端
格式输出(见下文),而在后者中,它将理解这两个文件都是 HTML)。
可以通过指定以下内容来覆盖此行为:
--input-format=[text|html]
或--output-format=[terminal|html|markdown]
.
关于 终端
输出格式的说明:它被设计为将文本打印到终端,通过使用 UNIX 终端特殊字符下划线和着色一些单词(见上截图)。因此,它仅在未给出输出文件名且 Caribon 打印到标准输出时激活,HTML 输出是大多数情况下的默认设置。
文本统计
--print-stats
,如果传递给 Caribon,还将在标准输出上显示输入文本的一些统计信息。
阈值和最大距离
Caribon 最有用的算法是本地重复检测。它检测在给定单词间隔内单词是否重复。此间隔由
--max-distance=[value]
(当前默认值是 50)确定。
因此,如果 max-distance
为 50,并且单词 'foo' 在此间隔内出现两次,则每次出现的重复值都为 2。如果 'foo' 在第二个出现后的 50 个单词间隔内第三次重复,则这些出现的重复值都为 3。(如果之后有超过 50 个单词没有出现 'foo',并且 'foo' 再次出现,则最新出现的值将重置为 1)。
当单词的“重复值”高于阈值时,单词会被下划线标出,该阈值可以通过
--threshold=[value]
设置。默认值是1.9
,因此单词在重复两次后就会被下划线标出。如果您将阈值更改为,例如,2.5
,则单词必须重复三次(本地)才能被下划线标出。
(为什么阈值使用浮点值而不是整数?因为本地重复检测器会根据重复的“严重程度”以不同颜色(绿色、橙色和红色)下划线标出单词。因此,将阈值设置为 1.01
或 1.99
不会改变哪些单词被下划线标出,但第一种情况下单词更快地出现在橙色或红色中。)
模糊字符串匹配
Caribon 使用一个词干库来检测属于同一“家族”的单词。结果发现,此算法并不总是足够,尤其是当存在拼写错误时(例如,“higlight”和“highlight”可能应该被认为是重复的,即使第一个拼写有误)。为了解决这个问题,有激活模糊字符串匹配的选项。
fuzzy=[value]
,其中值是一个介于0.0和1.0之间的数字,它表示两个单词之间的“差异”最大值,直到它们不再相同:0.2的值意味着两个单词最多只能“差异20%”才被视为相同。
该算法内部使用Levenshtein距离(以及更具体的是Florian Ebelling的Rust实现),通过估计将一个字符串转换为另一个字符串所需的插入、删除和排列次数来计算两个字符串之间的距离。例如,“dog”和“dogs”的距离为1,而“dog”和“cat”的距离为3。然后将此值除以匹配字符串的长度,当此值小于给定的--fuzzy=
值时,两个字符串被认为是“相同”(或至少是重复)。
例如,使用--fuzzy=0.2
,"highlight"和"higlight"之间的“差异”估计为1/9(Levenshtein距离为1,只需要一次删除就可以从第一个转换为第二个,除以"highlight"的长度,9),因此它将被视为重复。"Just"和"Rust"之间的“差异”为1/4,所以不会被考虑为重复。
模糊匹配实用,但不应将其设置得过高,否则会有很多误报。经验表明,0.2
或0.25
是一个不错的选择。
模糊匹配的缺点是它需要更多的CPU资源。Caribon仍然可以运行得相当快(例如,在启用模糊字符串匹配的情况下检测整篇小说的重复内容不到一秒),但它仅用于局部重复,而不是全局重复(见下文)。
全局重复
默认情况下,Caribon仅检测小于max-distance
单词间隔的局部重复。然而,可以通过以下方式激活全局重复检测:
--global-threshold=[value]
,其中value是一个介于0.0和1.0之间的数字。
在这种情况下,如果一个单词的相对出现次数高于全局阈值(即使在一个max-distance
范围内从未重复过),则该单词将被视为重复。即如果将global-threshold
设置为0.01,则如果一个单词在文档中占总单词数的1%以上,它将被突出显示(蓝色)。
忽略的单词
一些单词,如"a"或"the",不可避免地会重复很多次,而且将它们视为重复没有太大意义。因此,忽略一些单词很有用。Caribon
为英语和法语提供了默认列表,但在所有情况下都可以使用以下方式提供自己的列表:
--ignore="常见单词列表"
.
此列表必须由空格或逗号(实际上,可以是任何非字母字符)分隔,并且必须用引号括起来。此列表替代Caribon提供的默认列表(至少对于英语和法语)。如果您想要添加单词到该列表而不是替换它,请使用:
--add-ignored="更多忽略单词列表"
忽略单词的另一种方法是:
--ignore-proper=[true|false]
(默认为false)
如果设置为true,Caribon将尝试忽略专有名词。也就是说,如果一个单词以大写字母开头且不在句子的开头,则它不会计入重复。
库
Caribon 可以作为一个 Rust 库使用。文档可在此处找到;为了确保下载的代码对应的文档版本,您也可以使用以下命令生成:cargo doc
。
Caribon 库也可在Crates.io找到,允许您轻松地在任何 Cargo 项目中使用它:只需在 Cargo.toml
文件的依赖部分添加
caribon= "0.7"
。
Caribon-server
如果您不喜欢命令行界面,可以查看Caribon-server,它将 Caribon 作为 Web 服务运行(使用Iron 框架)。关于运行实例的详细信息,请参阅此处。
当前功能
- 内置了法语和英语的忽略词列表(重复次数不重要的常见词),尽管它们并不完整。
- 支持 Snowball(《http://snowball.tartarus.org/》)项目支持的语言的词干提取。
- 此外(因为词干提取算法并不总是完美的,有时您会犯拼写错误),支持模糊字符串匹配(基于 Levenhstein 距离)。
- 本地和全局计数重复。
- 检测输入中的 HTML 标签。通常对 HTML 片段或完整 HTML 页面都有效。
- 将检测到的重复内容输出到 HTML 文件(最有用的选项)、直接输出到终端或 Markdown 文件(信息较少)。
变更日志
许可证
Caribon 根据GNU Lesser General Public License,版本 2.1 或(方便起见)任何后续版本进行许可。
致谢
Caribon 由 Élisabeth Henry 编写,电子邮件为 <liz.henry at ouvaton.org>
。
本软件使用了(Rust 绑定)由 Dr Martin Porter 编写的C 词干提取库,许可证为 BSD 许可证。
它还使用了由 Florian Ebelling 编写的 Levenshtein 距离的 Rust 实现Rust implementation,许可证为 Apache 2.0 许可证。
待办事项
库
- 使颜色高亮更可配置
- 完成内置的忽略词列表,并为其他语言提供(目前只有法语和英语);
- 提供检测表达式重复的算法,而不仅仅是单个单词的重复;
- 使库可以从 C(以及其他语言,如 Rust)调用;
- 增强文档并添加测试。
程序
- 添加选项以选择高亮颜色
- 找到更好的默认值?
- 为程序和库创建不同的存储库?
- 添加带有 GUI(Gtk+?)的变体?
依赖项
~640KB
~17K SLoC