Skip to main content

pattern_width

Function pattern_width 

Source
pub fn pattern_width(pattern: &str) -> Result<Width>
Expand description

Parse pattern and return the minimum and maximum number of characters it can match.

This is a convenience wrapper around parse + width::node_width.

use re_parser::pattern_width;

let w = pattern_width(r"\d{4}-\d{2}-\d{2}").unwrap();
assert_eq!(w.min, 10);
assert_eq!(w.max, Some(10));
assert!(w.is_fixed());
Examples found in repository?
examples/width.rs (line 58)
25fn main() {
26    println!("=== Fixed-width patterns ===");
27    report("abc");
28    report(r"\d{4}-\d{2}-\d{2}");           // ISO date → 10
29    report(r"#[0-9a-fA-F]{6}");             // CSS hex colour → 7
30    report(r"[A-Z]{2}[0-9]{4}");            // plate → 6
31
32    println!("\n=== Variable but bounded patterns ===");
33    report(r"\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}"); // IPv4 → 7..=15
34    report(r"https?://");                    // 7..=8
35    report(r"[a-zA-Z]{2,8}");               // 2..=8
36    report(r"colou?r");                     // 5..=6
37
38    println!("\n=== Unbounded patterns ===");
39    report(r"\w+");                          // 1..∞
40    report(r".*");                           // 0..∞
41    report(r"\S+@\S+\.\S+");               // 5..∞
42    report(r"(?:ab)+");                     // 2..∞
43
44    println!("\n=== Anchors and lookarounds are zero-width ===");
45    report(r"^hello$");                     // anchors → still 5
46    report(r"foo(?=bar)");                  // lookahead → 3
47    report(r"(?<=\d)px");                   // lookbehind → 2
48    report(r"\bword\b");                    // \b → 4
49
50    println!("\n=== Alternation ===");
51    report(r"cat|dog");                     // exactly 3
52    report(r"a|bb|ccc");                    // 1..=3
53    report(r"yes|no");                      // 2..=3
54    report(r"x|\d+");                       // 1..∞
55
56    // ── using pattern_width convenience function ───────────────────────────
57    println!("\n=== pattern_width() convenience wrapper ===");
58    let w = pattern_width(r"a{2,5}").unwrap();
59    println!("  a{{2,5}} => {w}");
60    println!("    is_fixed:     {}", w.is_fixed());
61    println!("    is_nullable:  {}", w.is_nullable());
62    println!("    is_unbounded: {}", w.is_unbounded());
63
64    // ── calling methods on a sub-node ──────────────────────────────────────
65    println!("\n=== Inspecting sub-nodes ===");
66    let ast = parse(r"(\d{4})-(\d{2})-(\d{2})").unwrap();
67    println!("  full pattern  min={} max={:?}", ast.min_width(), ast.max_width());
68
69    // Walk the top-level Concat children manually
70    if let re_parser::ast::Regex::Concat(nodes) = &ast {
71        for (i, node) in nodes.iter().enumerate() {
72            println!(
73                "  child[{i}]  min={}  max={:?}  node={node:?}",
74                node.min_width(),
75                node.max_width(),
76            );
77        }
78    }
79}