aho-corasick
这是一个用于同时查找多个模式的库,在某些情况下使用SIMD加速。该库主要通过实现Aho-Corasick算法来提供多模式搜索,该算法构建了一个有限状态机,以线性时间执行搜索。特性包括不区分大小写的匹配、重叠匹配、通过SIMD实现的快速搜索,以及可选的完整DFA构建和流中的搜索与替换。
采用MIT或UNLICENSE双重许可。
文档
使用方法
运行cargo add aho-corasick
以自动将此crate添加为您的Cargo.toml
文件中的依赖项。
示例:基本搜索
此示例展示了如何同时搜索多个模式的出现。每个匹配包括匹配的模式以及匹配的字节偏移量。
use aho_corasick::{AhoCorasick, PatternID};
let patterns = &["apple", "maple", "Snapple"];
let haystack = "Nobody likes maple in their apple flavored Snapple.";
let ac = AhoCorasick::new(patterns).unwrap();
let mut matches = vec![];
for mat in ac.find_iter(haystack) {
matches.push((mat.pattern(), mat.start(), mat.end()));
}
assert_eq!(matches, vec![
(PatternID::must(1), 13, 18),
(PatternID::must(0), 28, 33),
(PatternID::must(2), 43, 50),
]);
示例:ASCII不区分大小写
这个示例类似于前一个示例,但使用AhoCorasickBuilder
对Snapple
进行不区分大小写的匹配:
use aho_corasick::{AhoCorasick, PatternID};
let patterns = &["apple", "maple", "snapple"];
let haystack = "Nobody likes maple in their apple flavored Snapple.";
let ac = AhoCorasick::builder()
.ascii_case_insensitive(true)
.build(patterns)
.unwrap();
let mut matches = vec![];
for mat in ac.find_iter(haystack) {
matches.push((mat.pattern(), mat.start(), mat.end()));
}
assert_eq!(matches, vec![
(PatternID::must(1), 13, 18),
(PatternID::must(0), 28, 33),
(PatternID::must(2), 43, 50),
]);
示例:在流中替换匹配项
此示例展示了如何在不首先将整个流加载到内存中的情况下执行搜索和替换。
use aho_corasick::AhoCorasick;
let patterns = &["fox", "brown", "quick"];
let replace_with = &["sloth", "grey", "slow"];
// 在实际例子中,这些可能是 `std::fs::File`。你只需要
// 提供一对 `std::io::Read` 和 `std::io::Write` 的实现。
let rdr = "The quick brown fox.";
let mut wtr = vec![];
let ac = AhoCorasick::new(patterns).unwrap();
ac.stream_replace_all(rdr.as_bytes(), &mut wtr, replace_with)
.expect("stream_replace_all 失败");
assert_eq!(b"The slow grey sloth.".to_vec(), wtr);
示例:查找最左侧的第一个匹配
在Aho-Corasick算法的教科书描述中,其表述通常结构化为报告所有可能的匹配,即使它们与另一个重叠。在许多情况下,可能不需要重叠匹配,比如像标准正则表达式那样查找所有连续的非重叠匹配。
不幸的是,修改Aho-Corasick算法以实现这一点的"显而易见"的方法并不总是按预期工作,因为它会在看到匹配时立即报告。例如,考虑在文本"Samwise"中匹配正则表达式"Samwise|Sam"。大多数正则表达式引擎(类Perl的或非POSIX的)会报告"Samwise"作为匹配,但为报告非重叠匹配而修改的标准Aho-Corasick算法会报告"Sam"。
这个库的一个新颖贡献是能够改变Aho-Corasick的匹配语义(无需额外的搜索时间开销),使得报告"Samwise"。例如,这是标准方法:
use aho_corasick::AhoCorasick;
let patterns = &["Samwise", "Sam"];
let haystack = "Samwise";
let ac = AhoCorasick::new(patterns).unwrap();
let mat = ac.find(haystack).expect("应该有匹配");
assert_eq!("Sam", &haystack[mat.start()..mat.end()]);
现在这是最左优先版本,它匹配Perl类正则表达式的工作方式:
use aho_corasick::{AhoCorasick, MatchKind};
let patterns = &["Samwise", "Sam"];
let haystack = "Samwise";
let ac = AhoCorasick::builder()
.match_kind(MatchKind::LeftmostFirst)
.build(patterns)
.unwrap();
let mat = ac.find(haystack).expect("应该有匹配");
assert_eq!("Samwise", &haystack[mat.start()..mat.end()]);
除了最左优先语义外,这个库还支持最左最长语义,它匹配正则表达式交替的POSIX行为。更多详情请参见文档中的MatchKind
。
最低Rust版本策略
此crate支持的最低rustc
版本是1.60.0
。
当前策略是,使用此crate所需的最低Rust版本可以在次要版本更新中增加。例如,如果crate 1.0
需要Rust 1.20.0,那么对于所有z
值,crate 1.0.z
也将需要Rust 1.20.0或更新版本。然而,对于y > 0
的crate 1.y
可能需要更新的最低Rust版本。
总的来说,这个crate在支持的Rust最低版本方面会采取保守策略。
FFI绑定
- G-Research/ahocorasick_rs 是该库的Python封装。
- tmikus/ahocorasick_rs 是该库的Go 语言封装。