Rust正则表达式解析库tree-sitter-regex的使用,支持高效语法树构建和模式匹配
tree-sitter-regex
安装
在项目目录中运行以下Cargo命令:
cargo add tree-sitter-regex
或者在Cargo.toml中添加以下行:
tree-sitter-regex = "0.24.3"
使用示例
下面是一个使用tree-sitter-regex库解析正则表达式并构建语法树的完整示例:
use tree_sitter::Parser;
use tree_sitter_regex::language;
fn main() {
// 创建解析器
let mut parser = Parser::new();
// 设置正则表达式语言
let language = language();
parser.set_language(language).unwrap();
// 要解析的正则表达式
let regex = r"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$";
// 解析正则表达式
let tree = parser.parse(regex, None).unwrap();
// 获取根节点
let root_node = tree.root_node();
// 打印语法树
println!("Syntax tree:");
print_tree(&root_node, 0);
}
// 递归打印语法树
fn print_tree(node: &tree_sitter::Node, depth: usize) {
let indent = " ".repeat(depth);
println!("{}{:?}", indent, node);
let mut cursor = node.walk();
for child in node.children(&mut cursor) {
print_tree(&child, depth + 1);
}
}
功能特点
- 高效的正则表达式语法解析
- 构建详细的语法树结构
- 支持正则表达式模式匹配
- 与其他tree-sitter工具集成
完整示例demo
下面是一个更完整的示例,展示如何解析不同的正则表达式模式并分析语法树:
use tree_sitter::{Parser, Node};
use tree_sitter_regex::language;
fn main() {
// 初始化解析器
let mut parser = Parser::new();
parser.set_language(language()).unwrap();
// 测试不同的正则表达式模式
let patterns = vec![
r"\d{3}-\d{2}-\d{4}", // 社会安全号码模式
r"[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}", // 电子邮件模式
r"^(https?:\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?$", // URL模式
r"(\d{1,3}\.){3}\d{1,3}", // IP地址模式
];
for pattern in patterns {
println!("\n解析正则表达式: {}", pattern);
// 解析正则表达式
let tree = parser.parse(pattern, None).unwrap();
let root = tree.root_node();
// 打印语法树
println!("语法树结构:");
print_tree(&root, 0);
// 分析特定节点
analyze_pattern(&root);
}
}
fn print_tree(node: &Node, depth: usize) {
let indent = " ".repeat(depth);
println!("{}{:?}", indent, node);
let mut cursor = node.walk();
for child in node.children(&mut cursor) {
print_tree(&child, depth + 1);
}
}
fn analyze_pattern(root: &Node) {
let mut cursor = root.walk();
println!("\n正则表达式分析结果:");
// 遍历所有量词节点
for node in root.children(&mut cursor) {
if node.kind() == "quantifier" {
println!(" - 找到量词: {}", node.utf8_text(root.start_byte()).unwrap());
}
}
// 检查字符类
for node in root.children(&mut cursor) {
if node.kind() == "character_class" {
println!(" - 找到字符类: {}", node.utf8_text(root.start_byte()).unwrap());
}
}
}
功能特点
- 高效的正则表达式语法解析
- 构建详细的语法树结构
- 支持正则表达式模式匹配
- 与其他tree-sitter工具集成
1 回复
Rust正则表达式解析库tree-sitter-regex使用指南
概述
tree-sitter-regex是一个基于Tree-sitter的Rust正则表达式解析库,能够将正则表达式解析为语法树,支持高效的语法分析和模式匹配操作。
主要特性
- 将正则表达式解析为语法树结构
- 支持高效的模式匹配
- 提供详细的语法节点信息
- 可与其他Tree-sitter工具集成
安装方法
在Cargo.toml中添加依赖:
[dependencies]
tree-sitter-regex = "0.20.0"
tree-sitter = "0.20.0"
基本使用方法
1. 解析正则表达式
use tree_sitter::Parser;
use tree_sitter_regex::language;
fn main() {
// 创建解析器实例
let mut parser = Parser::new();
// 设置正则表达式语言
parser.set_language(language()).unwrap();
// 定义要解析的正则表达式(电子邮件验证)
let regex = r"^[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,}$";
// 解析正则表达式
let tree = parser.parse(regex, None).unwrap();
// 打印语法树的S表达式表示
println!("{}", tree.root_node().to_sexp());
}
2. 遍历语法树
// 递归打印语法树节点
fn print_nodes(node: tree_sitter::Node, source: &str, depth: usize) {
// 创建缩进字符串
let indent = " ".repeat(depth);
// 打印节点类型和内容
println!("{}{:?} - {}", indent, node.kind(), node.utf8_text(source.as_bytes()).unwrap());
// 创建游标遍历子节点
let mut cursor = node.walk();
// 递归打印所有子节点
for child in node.children(&mut cursor) {
print_nodes(child, source, depth + 1);
}
}
3. 模式匹配检查
use tree_sitter_regex::RegexQuery;
// 检查文本是否匹配正则表达式
fn check_pattern(regex: &str, text: &str) -> bool {
// 创建正则查询
let query = RegexQuery::new(regex).unwrap();
// 检查匹配
query.matches(text)
}
fn main() {
// 电子邮件正则表达式
let email_regex = r"^[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,}$";
// 测试有效电子邮件
println!("Valid email? {}", check_pattern(email_regex, "test@example.com")); // true
// 测试无效电子邮件
println!("Valid email? {}", check_pattern(email_regex, "invalid-email")); // false
}
高级用法
1. 提取匹配组
use tree_sitter_regex::RegexQuery;
// 提取正则表达式匹配的组
fn extract_groups(regex: &str, text: &str) {
// 创建正则查询
let query = RegexQuery::new(regex).unwrap();
// 获取捕获组
if let Some(captures) = query.captures(text) {
// 打印所有捕获组
for (i, group) in captures.iter().enumerate() {
println!("Group {}: {:?}", i, group.map(|g| g.to_string()));
}
}
}
fn main() {
// 日期正则表达式(包含捕获组)
let date_regex = r"(\d{4})-(\d{2})-(\d{2})";
// 提取日期各部分
extract_groups(date_regex, "2023-05-15");
// 输出:
// Group 0: Some("2023-05-15")
// Group 1: Some("2023")
// Group 2: Some("05")
// Group 3: Some("15")
}
2. 语法树可视化
use tree_sitter::Parser;
use tree_sitter_regex::language;
// 可视化正则表达式语法树
fn visualize_tree(regex: &str) {
// 创建解析器
let mut parser = Parser::new();
parser.set_language(language()).unwrap();
// 解析正则表达式
let tree = parser.parse(regex, None).unwrap();
// 使用栈进行深度优先遍历
let mut cursor = tree.walk();
let mut stack = vec![(cursor.node(), 0)];
while let Some((node, depth)) = stack.pop() {
// 打印节点类型和缩进
let indent = " ".repeat(depth);
println!("{}{:?}", indent, node.kind());
// 收集子节点并逆序(因为栈是后进先出)
let mut child_cursor = node.walk();
let mut children: Vec<_> = node.children(&mut child_cursor).collect();
children.reverse();
// 将子节点压入栈
for child in children {
stack.push((child, depth + 1));
}
}
}
fn main() {
// 可视化社保号格式正则表达式
visualize_tree(r"\d{3}-\d{2}-\d{4}");
}
性能优化建议
- 重用Parser实例:Parser创建成本较高,应尽量重用
- 预编译常用正则表达式:将频繁使用的正则表达式预先解析为RegexQuery
- 使用更简单的正则表达式:复杂正则表达式会生成更大的语法树,影响性能
常见问题
1. 不支持的正则特性
tree-sitter-regex可能不支持某些高级正则特性,如:
- 后向引用
- 复杂的断言
- 某些递归模式
2. 错误处理
use tree_sitter_regex::RegexQuery;
// 安全解析正则表达式
fn safe_parse(regex: &str) -> Result<RegexQuery, String> {
RegexQuery::new(regex).map_err(|e| format!("Regex parse error: {:?}", e))
}
fn main() {
// 测试无效正则表达式
match safe_parse(r"invalid[regex") {
Ok(_) => println!("Valid regex"),
Err(e) => println!("Error: {}", e),
}
}
完整示例代码
下面是一个结合了上述功能的完整示例:
use tree_sitter::{Parser, Node};
use tree_sitter_regex::{language, RegexQuery};
fn main() {
// 1. 解析正则表达式
let mut parser = Parser::new();
parser.set_language(language()).unwrap();
let regex_pattern = r"(\w+)=(\d+)";
let tree = parser.parse(regex_pattern, None).unwrap();
println!("Syntax tree:\n{}", tree.root_node().to_sexp());
// 2. 遍历语法树
println!("\nTree traversal:");
print_nodes(tree.root_node(), regex_pattern, 0);
// 3. 模式匹配检查
println!("\nPattern matching:");
let text_to_match = "count=42";
println!("Does '{}' match pattern? {}", text_to_match,
check_pattern(regex_pattern, text_to_match));
// 4. 提取匹配组
println!("\nCaptured groups:");
extract_groups(regex_pattern, text_to_match);
// 5. 语法树可视化
println!("\nTree visualization:");
visualize_tree(regex_pattern);
// 6. 错误处理示例
println!("\nError handling:");
match safe_parse(r"invalid[regex") {
Ok(_) => println!("Valid regex"),
Err(e) => println!("Error: {}", e),
}
}
// 遍历语法树的辅助函数
fn print_nodes(node: Node, source: &str, depth: usize) {
let indent = " ".repeat(depth);
println!("{}{:?} - {}", indent, node.kind(), node.utf8_text(source.as_bytes()).unwrap());
let mut cursor = node.walk();
for child in node.children(&mut cursor) {
print_nodes(child, source, depth + 1);
}
}
// 检查模式匹配的辅助函数
fn check_pattern(regex: &str, text: &str) -> bool {
RegexQuery::new(regex).unwrap().matches(text)
}
// 提取捕获组的辅助函数
fn extract_groups(regex: &str, text: &str) {
let query = RegexQuery::new(regex).unwrap();
if let Some(captures) = query.captures(text) {
for (i, group) in captures.iter().enumerate() {
println!("Group {}: {:?}", i, group.map(|g| g.to_string()));
}
}
}
// 可视化语法树的辅助函数
fn visualize_tree(regex: &str) {
let mut parser = Parser::new();
parser.set_language(language()).unwrap();
let tree = parser.parse(regex, None).unwrap();
let mut cursor = tree.walk();
let mut stack = vec![(cursor.node(), 0)];
while let Some((node, depth)) = stack.pop() {
let indent = " ".repeat(depth);
println!("{}{:?}", indent, node.kind());
let mut child_cursor = node.walk();
let mut children: Vec<_> = node.children(&mut child_cursor).collect();
children.reverse();
for child in children {
stack.push((child, depth + 1));
}
}
}
// 安全解析的辅助函数
fn safe_parse(regex: &str) -> Result<RegexQuery, String> {
RegexQuery::new(regex).map_err(|e| format!("Regex parse error: {:?}", e))
}
这个完整示例演示了tree-sitter-regex库的主要功能:
- 解析正则表达式为语法树
- 遍历和可视化语法树结构
- 进行模式匹配检查
- 提取匹配的捕获组
- 处理可能出现的错误
tree-sitter-regex为Rust开发者提供了强大的正则表达式解析能力,特别适合需要深入分析正则表达式结构或构建正则相关工具的场景。