monster_regex/captures/mod.rs
1/// Represents a single match within the text, defined by a start and end byte offset.
2#[derive(Debug, Clone, PartialEq, Eq)]
3pub struct Match {
4 /// The byte index where the match starts (inclusive).
5 pub start: usize,
6 /// The byte index where the match ends (exclusive).
7 pub end: usize,
8}
9
10impl Match {
11 /// Returns the length of the match in bytes.
12 pub fn len(&self) -> usize {
13 self.end - self.start
14 }
15
16 /// Returns true if the match has a length of 0.
17 pub fn is_empty(&self) -> bool {
18 self.start == self.end
19 }
20
21 /// Returns the substring of the original text corresponding to this match.
22 ///
23 /// # Panics
24 ///
25 /// Panics if the indices are out of bounds of the provided text or do not lie on UTF-8 boundaries.
26 pub fn as_str<'a>(&self, text: &'a str) -> &'a str {
27 &text[self.start..self.end]
28 }
29}
30
31/// Represents the results of a regex match, including the full match and any captured groups.
32#[derive(Debug, Clone)]
33pub struct Captures {
34 /// The match corresponding to the entire regex pattern (group 0).
35 pub full_match: Match,
36 /// Ordered list of captured groups (group 1, group 2, etc.).
37 /// `None` indicates the group exists in the pattern but did not participate in the match.
38 pub groups: Vec<Option<Match>>,
39 /// Map of named capture groups to their matches.
40 pub named: std::collections::HashMap<String, Match>,
41}
42
43impl Captures {
44 /// Returns the match associated with the capture group at `index`.
45 ///
46 /// * `0` corresponds to the entire match.
47 /// * `1..` corresponds to the parenthesized capture groups.
48 ///
49 /// Returns `None` if the index is out of bounds or if the group did not participate in the match.
50 pub fn get(&self, index: usize) -> Option<&Match> {
51 if index == 0 {
52 Some(&self.full_match)
53 } else {
54 self.groups.get(index - 1).and_then(|g| g.as_ref())
55 }
56 }
57
58 /// Returns the match associated with a named capture group.
59 pub fn get_named(&self, name: &str) -> Option<&Match> {
60 self.named.get(name)
61 }
62
63 /// Returns the substring of the original text for the capture group at `index`.
64 pub fn as_str<'a>(&self, text: &'a str, index: usize) -> Option<&'a str> {
65 self.get(index).map(|m| m.as_str(text))
66 }
67
68 /// Returns the substring of the original text for a named capture group.
69 pub fn as_str_named<'a>(&self, text: &'a str, name: &str) -> Option<&'a str> {
70 self.get_named(name).map(|m| m.as_str(text))
71 }
72}