1use re_parser::ast::{GroupKind, Regex};
10use re_parser::parse;
11
12fn group_kind_label(kind: &GroupKind) -> &'static str {
13 match kind {
14 GroupKind::Capturing => "capturing",
15 GroupKind::Named(_) => "named capturing",
16 GroupKind::NonCapturing => "non-capturing",
17 GroupKind::LookaheadPos => "positive lookahead",
18 GroupKind::LookaheadNeg => "negative lookahead",
19 GroupKind::LookbehindPos => "positive lookbehind",
20 GroupKind::LookbehindNeg => "negative lookbehind",
21 }
22}
23
24fn print_group(pattern: &str) {
25 let ast = parse(pattern).unwrap();
26
27 let group_node = match &ast {
30 Regex::Group(_, _) => Some(&ast),
31 Regex::Concat(nodes) => nodes.iter().find(|n| matches!(n, Regex::Group(_, _))),
32 _ => None,
33 };
34
35 match group_node {
36 Some(Regex::Group(inner, kind)) => {
37 let label = group_kind_label(kind);
38 let name_part = if let GroupKind::Named(n) = kind {
39 format!(" (name = \"{n}\")")
40 } else {
41 String::new()
42 };
43 println!(
44 " {pattern:20} => {label}{name_part}, inner = {:?}",
45 inner
46 );
47 }
48 _ => println!(" {pattern:20} => {ast:?}"),
49 }
50}
51
52fn main() {
53 println!("=== Capturing & non-capturing ===");
54 print_group("(abc)");
55 print_group("(?:abc)");
56 print_group("(?P<word>\\w+)");
57
58 println!("\n=== Lookahead assertions ===");
59 print_group("foo(?=bar)"); print_group("foo(?!bar)"); println!("\n=== Lookbehind assertions ===");
63 print_group("(?<=\\d)px"); print_group("(?<!\\d)px"); println!("\n=== Nested groups (full pretty AST) ===");
67 let pattern = "(?P<date>(?P<year>\\d{4})-(?P<month>\\d{2}))";
68 println!(" Pattern: {pattern}");
69 println!(" AST:\n{:#?}", parse(pattern).unwrap());
70}