Rust超链接解析库parse-hyperlinks的使用,高效提取与处理文本中的URL链接
Rust超链接解析库parse-hyperlinks的使用,高效提取与处理文本中的URL链接
Parse-hyperlinks是一个用Nom编写的解析器库,用于识别Markdown、reStructuredText、Asciidoc和HTML格式文本输入中的超链接和链接引用定义。
该库实现了CommonMark规范0.30、reStructuredText标记规范(修订版8571,日期2020-10-28)、Asciidoctor用户手册第26章(日期2020-12-03)和HTML 5.2第4.5节中的规范。
Parse-Hyperlinks输入约定
- 所有输入都是UTF-8编码的
- 输入文本根据上述标记语言规范之一进行格式化
HTML文档的额外输入约定
- HTML文档中绝对URL中的字符
&<>"
必须进行HTML转义编码 - UTF-8编码的HTML文档中的相对URL不需要HTML转义编码
- 相对URL不能以方案开头(如
http:
) - URL可以同时进行HTML转义编码和百分比编码
完整示例代码
以下是内容中提供的示例:
use parse_hyperlinks::{extract_links, Link};
fn main() {
// 示例文本包含多种格式的链接
let text = r#"
这是一个包含多种链接格式的文本:
1. Markdown内联链接: [Rust官网](https://www.rust-lang.org)
2. Markdown自动链接: <https://crates.io>
3. HTML链接: <a href="https://doc.rust-lang.org">Rust文档</a>
4. 纯文本URL: 访问https://github.com/rust-lang
"#;
// 提取所有链接
let links = extract_links(text);
println!("在文本中找到的链接:");
for (i, link) in links.iter().enumerate() {
println!("{}. {} -> {}", i + 1, link.text, link.destination);
}
// 处理特定类型的链接
let markdown_links: Vec<&Link> = links.iter()
.filter(|l| l.format == "markdown")
.collect();
println!("\nMarkdown链接:");
for link in markdown_links {
println!("- {}: {}", link.text, link.destination);
}
}
扩展示例代码
以下是一个更完整的示例,展示如何处理不同类型的链接并输出统计信息:
use parse_hyperlinks::{extract_links, Link};
fn main() {
// 包含多种格式的混合文本
let text = r#"
# 示例文档
## 段落1
这是一个[Markdown链接](https://example.com),以及一个HTML链接:
<a href="https://html.example.com">HTML示例</a>。
## 段落2
自动链接: <https://auto.example.com>
纯文本URL: 访问https://text.example.com了解更多。
## 段落3
参考式链接: [参考链接][id]
[id]: https://reference.example.com "参考标题"
"#;
// 提取所有链接
let links = extract_links(text);
// 统计不同类型链接的数量
let mut markdown_count = 0;
let mut html_count = 0;
let mut auto_count = 0;
let mut text_count = 0;
for link in &links {
match link.format.as_str() {
"markdown" => markdown_count += 1,
"html" => html_count += 1,
"auto" => auto_count += 1,
"text" => text_count += 1,
_ => (),
}
}
println!("链接统计:");
println!("- Markdown链接: {}", markdown_count);
println!("- HTML链接: {}", html_count);
println!("- 自动链接: {}", auto_count);
println!("- 纯文本URL: {}", text_count);
println!("- 总链接数: {}", links.len());
// 输出所有链接详情
println!("\n链接详情:");
for (i, link) in links.iter().enumerate() {
println!("{}. [{}] {} -> {}",
i + 1,
link.format,
link.text,
link.destination
);
}
}
安装
在项目目录中运行以下Cargo命令:
cargo add parse-hyperlinks
或者在Cargo.toml中添加以下行:
parse-hyperlinks = "0.29.0"
主要功能
- 支持多种标记语言的链接解析
- 高效提取文本中的URL
- 区分不同类型的链接(Markdown、HTML等)
- 处理转义和编码的URL
- 轻量级且快速
这个库特别适合需要从混合格式文本中提取和分析链接的应用场景,如文档处理工具、爬虫或内容分析系统。
1 回复
Rust超链接解析库parse-hyperlinks使用指南
parse-hyperlinks
是一个高效的Rust库,专门用于从文本中提取和处理URL链接。它提供了简单易用的API,能够快速识别文本中的各种格式的超链接。
功能特性
- 支持提取HTTP/HTTPS/FTP等常见协议的URL
- 识别包含在尖括号、引号或纯文本中的链接
- 高性能的解析算法
- 可配置的解析选项
- 支持相对URL的解析(需配合基础URL)
安装方法
在Cargo.toml中添加依赖:
[dependencies]
parse-hyperlinks = "0.3"
基本使用方法
简单提取链接
use parse_hyperlinks::find_links;
fn main() {
// 示例文本包含多个URL
let text = "Visit my website at https://example.com or check out https://rust-lang.org";
// 使用find_links函数提取所有链接
let links = find_links(text);
// 打印找到的所有链接
for link in links {
println!("Found link: {}", link.as_str());
}
}
处理HTML中的链接
use parse_hyperlinks::{find_links, Link};
fn main() {
// HTML示例文本
let html = r#"
<a href="https://example.com/page1">Link 1</a>
<img src="https://example.com/image.png" alt="Example">
"#;
// 提取HTML中的链接
let links = find_links(html);
// 对不同类型的链接进行分类处理
for link in links {
match link {
Link::Url(url) => println!("URL: {}", url),
Link::Email(email) => println!("Email: {}", email),
}
}
}
高级配置选项
use parse_hyperlinks::{LinkFinder, LinkKind};
fn main() {
let text = "Contact me at user@example.com or visit https://example.com";
// 创建LinkFinder实例
let mut finder = LinkFinder::new();
// 配置只查找电子邮件地址
finder.kinds(&[LinkKind::Email]);
// 收集并打印找到的电子邮件
let links: Vec<_> = finder.links(text).collect();
println!("Found emails: {:?}", links);
}
处理相对URL
use parse_hyperlinks::{LinkFinder, Url};
fn main() {
// 基础URL,用于解析相对路径
let base_url = Url::parse("https://example.com/base/").unwrap();
let text = "Check out <a href='/about'>About page</a>";
// 创建LinkFinder并设置基础URL
let mut finder = LinkFinder::new();
finder.url(&base_url);
// 解析链接并打印绝对URL
let links = finder.links(text);
for link in links {
if let Some(url) = link.as_url() {
println!("Absolute URL: {}", url);
}
}
}
性能提示
use parse_hyperlinks::LinkFinder;
fn main() {
// 多个文本示例
let texts = vec![
"First text with https://link1.com",
"Second text with https://link2.org",
"Third text with contact@example.com"
];
// 重用LinkFinder实例提高性能
let mut finder = LinkFinder::new();
// 处理每个文本
for text in texts {
let links: Vec<_> = finder.links(text).collect();
println!("Found {} links in text", links.len());
}
}
错误处理
use parse_hyperlinks::LinkFinder;
use url::ParseError;
fn main() -> Result<(), ParseError> {
// 包含无效URL的文本
let text = "Invalid URL: https://example.com/%%invalid";
let finder = LinkFinder::new();
// 处理每个链接,区分有效和无效URL
for link in finder.links(text) {
match link.as_url() {
Some(url) => println!("Valid URL: {}", url),
None => println!("Invalid URL detected: {}", link.as_str()),
}
}
Ok(())
}
完整示例代码
下面是一个综合使用parse-hyperlinks库的完整示例:
use parse_hyperlinks::{LinkFinder, LinkKind, Link};
use url::Url;
fn main() -> Result<(), Box<dyn std::error::Error>> {
// 示例文本包含各种类型的链接
let content = r#"
<html>
<body>
<h1>Welcome</h1>
<p>Visit us at https://example.com</p>
<a href="/about">About</a>
<p>Contact: support@example.com</p>
<img src="logo.png" alt="Logo">
</body>
</html>
"#;
// 设置基础URL用于解析相对路径
let base_url = Url::parse("https://example.com")?;
// 配置LinkFinder
let mut finder = LinkFinder::new();
finder.url(&base_url); // 设置基础URL
finder.kinds(&[LinkKind::Url, LinkKind::Email]); // 查找URL和电子邮件
// 提取和处理链接
println!("Extracted links:");
for link in finder.links(content) {
match link {
Link::Url(url) => {
println!("- URL: {}", url);
}
Link::Email(email) => {
println!("- Email: {}", email);
}
}
}
Ok(())
}
这个完整示例演示了如何:
- 处理HTML内容中的链接
- 配置LinkFinder查找特定类型的链接
- 使用基础URL解析相对路径
- 区分处理URL和电子邮件链接
- 提供基本的错误处理
parse-hyperlinks
库非常适合需要从各种文本内容中提取链接的场景,它的高性能和灵活性使其成为Rust生态中链接处理的优秀选择。