Skip to main content

Regex

Struct Regex 

Source
pub struct Regex { /* private fields */ }
Expand description

A compiled regular expression.

A Regex is obtained by compiling a pattern with Regex::new (default flags) or Regex::new_with_flags, then used to search text via methods like find, is_match, find_iter, find_partial, replace and split.

Compilation is somewhat expensive; compile once and reuse the same Regex across many inputs. A Regex is Send + Sync once compiled (it owns no thread-local state) and is cheap to share by reference.

§Examples

use eregex::{flags, Regex};

let re = Regex::new(r"(\w+)@(\w+)")?;
let m = re.find("ping alice@work").unwrap();
assert_eq!(m.group(1), Some("alice"));
assert_eq!(m.group(2), Some("work"));

Implementations§

Source§

impl Regex

Source

pub fn new(pattern: &str) -> Result<Regex>

Compile pattern with the default flags.

§Errors

Returns Error if pattern is syntactically invalid (unbalanced parentheses, bad escape sequences, invalid quantifiers, unknown group names, etc.). See ErrorKind for the full list.

§Examples
use eregex::Regex;

let re = Regex::new(r"\d{3}-\d{2}")?;
assert!(re.is_match("123-45"));
assert!(Regex::new(r"(").is_err());
Examples found in repository?
examples/gap_match.rs (line 106)
103fn stm32_segments() -> Vec<Segment> {
104    vec![
105        Segment {
106            re: Regex::new(r"STM32F").unwrap(),
107            label: "STM32F",
108        },
109        Segment {
110            re: Regex::new(r"[0-9]{3}[A-Z0-9]{4}").unwrap(),
111            label: "407VGT6",
112        },
113    ]
114}
115
116/// The full, contiguous pattern used to re-validate the reconstruction and to
117/// recover clean capture groups (STM32 / F407 / VGT6).
118const FULL: &str = r"(STM32)(F[0-9]{3})([A-Z0-9]{4})";
119
120fn report(name: &str, hay: &str, max_gap: usize) {
121    println!("\n=== {name} ===");
122    println!("haystack: {hay:?}");
123
124    // (1) Show what the bare engine does — both strict and end-anchored partial.
125    let full = Regex::new(FULL).unwrap();
126    println!(
127        "  find         : {:?}",
128        full.find(hay).map(|m| m.as_str().to_string())
129    );
130    println!(
131        "  find_partial : {:?}",
132        match full.find_partial(hay) {
133            None => "None".to_string(),
134            Some(p) => format!("{:?} matched={:?}", p.status, p.matched),
135        }
136    );
137
138    // (2) Gap-tolerant shift-and-resume search.
139    match gap_find(hay, &stm32_segments(), max_gap) {
140        Some(gm) => {
141            println!("  gap_find     : OK");
142            println!("    reconstructed = {:?}", gm.reconstructed);
143            for (label, s, e) in &gm.segments {
144                println!("    segment {label:<8} = [{s}..{e}] {:?}", &hay[*s..*e]);
145            }
146            for (s, e) in &gm.skipped {
147                println!("    skipped        = [{s}..{e}] {:?}", &hay[*s..*e]);
148            }
149
150            // (3) Re-validate the reconstruction with the FULL pattern and
151            //     report clean groups. This is also where `find_partial`
152            //     earns its keep: it confirms Full vs Partial.
153            let p = full
154                .find_partial(&gm.reconstructed)
155                .expect("reconstruction must re-match the full pattern");
156            assert_eq!(p.status, MatchStatus::Full, "reconstruction must be Full");
157            println!(
158                "    groups = [STM32={:?}, F407={:?}, VGT6={:?}]",
159                p.group(1),
160                p.group(2),
161                p.group(3),
162            );
163
164            // The caller asked specifically about #2: group 2 (`F407`) is
165            // assembled from TWO non-contiguous haystack ranges — the `F` at
166            // the tail of segment 1 and the `407` at the head of segment 2.
167            if name.contains("#2") {
168                let (_, _, seg1_end) = gm.segments[0];
169                let (_, seg2_start, _) = gm.segments[1];
170                println!(
171                    "    group F407 split = [{}..{}] + [{}..{}]  (\"F\" + \"407\")",
172                    seg1_end - 1,
173                    seg1_end,
174                    seg2_start,
175                    seg2_start + 3
176                );
177            }
178        }
179        None => println!("  gap_find     : None (NoMatch)"),
180    }
181}
182
183fn main() {
184    // #2 / #10 — the main case: real noise between `F` and `407`.
185    // Gap = the " dutyu7 8 " run (≤ 16 bytes), so it is accepted.
186    report(
187        "#2 split by noise (max_gap=16)",
188        "Microcontroller STM32F dutyu7 8 407VGT6   ",
189        16,
190    );
191
192    // #9 — same shape, but max_gap=8 rejects the run.
193    report(
194        "#9 gap too long (max_gap=8)",
195        "Microcontroller STM32F very very very long unrelated text 407VGT6",
196        8,
197    );
198
199    // #7 — a wrong char *inside* the digits segment (`X` where a digit is
200    // expected). No `[0-9]{3}` run exists, so the segment search fails.
201    report(
202        "#7 wrong char inside series",
203        "Microcontroller STM32FX07VGT6",
204        16,
205    );
206
207    // #8 — wrong family (`STM8` instead of `STM32`): the first segment is
208    // never found.
209    report("#8 wrong family", "Microcontroller STM8F407VGT6", 16);
210
211    // #1 — the contiguous happy path: no gap, reconstruction == input tail.
212    report(
213        "#1 contiguous full match",
214        "Microcontroller STM32F407VGT6",
215        16,
216    );
217
218    println!("\n--- end-of-input partials (find_partial alone, no gap mode) ---");
219    let full = Regex::new(FULL).unwrap();
220    for hay in [
221        "Microcontroller STM32F",
222        "Microcontroller STM32F40",
223        "Microcontroller STM32F407VG",
224    ] {
225        let p = full.find_partial(hay).unwrap();
226        println!(
227            "  {:<32} -> {:?} matched={:?} g1={:?} g2={:?} g3={:?}",
228            hay,
229            p.status,
230            p.matched,
231            p.group(1),
232            p.group(2),
233            p.group(3)
234        );
235    }
236
237    println!("\nAll reconstruction checks passed.");
238}
More examples
Hide additional examples
examples/demo.rs (line 6)
5fn main() {
6    let re = Regex::new(r"(?P<word>\w+)\s+(?P<num>\d+)").unwrap();
7    let m = re.find("hello 42 world").unwrap();
8    println!("match: {:?}", m.as_str());
9    println!("word = {:?}", m.name("word"));
10    println!("num  = {:?}", m.name("num"));
11
12    // Repeated captures — a signature mrab-regex feature.
13    let re = Regex::new(r"(\w)+").unwrap();
14    let m = re.find("abc").unwrap();
15    println!("captures of group 1: {:?}", m.captures(1));
16
17    // Lookbehind (variable length) + case-insensitive.
18    let re = Regex::new(r"(?i)(?<=foo)bar").unwrap();
19    println!("lookbehind: {:?}", re.find("FOObar"));
20
21    // Atomic group prevents catastrophic backtracking.
22    let re = Regex::new(r"a(?>b*)b").unwrap();
23    println!("atomic find: {:?}", re.find("abbbbc"));
24
25    // Replace with named groups.
26    let re = Regex::new(r"(?P<first>\w+),(?P<second>\w+)").unwrap();
27    println!(
28        "replace: {}",
29        re.replace_all("a,b x,y", "${second} ${first}")
30    );
31
32    // Flags constant.
33    let re = Regex::new_with_flags(r"hello", flags::IGNORECASE | flags::MULTILINE).unwrap();
34    println!("flags: {:x}", re.flags().bits());
35}
Source

pub fn new_with_flags(pattern: &str, flags: Flags) -> Result<Regex>

Compile pattern with the given Flags.

§Errors

Returns Error on the same conditions as Regex::new.

§Examples
use eregex::{flags, Regex};

let re = Regex::new_with_flags(r"hello", flags::IGNORECASE)?;
assert_eq!(re.find("HELLO, World").unwrap().as_str(), "HELLO");
Examples found in repository?
examples/demo.rs (line 33)
5fn main() {
6    let re = Regex::new(r"(?P<word>\w+)\s+(?P<num>\d+)").unwrap();
7    let m = re.find("hello 42 world").unwrap();
8    println!("match: {:?}", m.as_str());
9    println!("word = {:?}", m.name("word"));
10    println!("num  = {:?}", m.name("num"));
11
12    // Repeated captures — a signature mrab-regex feature.
13    let re = Regex::new(r"(\w)+").unwrap();
14    let m = re.find("abc").unwrap();
15    println!("captures of group 1: {:?}", m.captures(1));
16
17    // Lookbehind (variable length) + case-insensitive.
18    let re = Regex::new(r"(?i)(?<=foo)bar").unwrap();
19    println!("lookbehind: {:?}", re.find("FOObar"));
20
21    // Atomic group prevents catastrophic backtracking.
22    let re = Regex::new(r"a(?>b*)b").unwrap();
23    println!("atomic find: {:?}", re.find("abbbbc"));
24
25    // Replace with named groups.
26    let re = Regex::new(r"(?P<first>\w+),(?P<second>\w+)").unwrap();
27    println!(
28        "replace: {}",
29        re.replace_all("a,b x,y", "${second} ${first}")
30    );
31
32    // Flags constant.
33    let re = Regex::new_with_flags(r"hello", flags::IGNORECASE | flags::MULTILINE).unwrap();
34    println!("flags: {:x}", re.flags().bits());
35}
Source

pub fn as_str(&self) -> &str

The original pattern string.

Source

pub fn flags(&self) -> Flags

The resolved flags in effect.

Examples found in repository?
examples/demo.rs (line 34)
5fn main() {
6    let re = Regex::new(r"(?P<word>\w+)\s+(?P<num>\d+)").unwrap();
7    let m = re.find("hello 42 world").unwrap();
8    println!("match: {:?}", m.as_str());
9    println!("word = {:?}", m.name("word"));
10    println!("num  = {:?}", m.name("num"));
11
12    // Repeated captures — a signature mrab-regex feature.
13    let re = Regex::new(r"(\w)+").unwrap();
14    let m = re.find("abc").unwrap();
15    println!("captures of group 1: {:?}", m.captures(1));
16
17    // Lookbehind (variable length) + case-insensitive.
18    let re = Regex::new(r"(?i)(?<=foo)bar").unwrap();
19    println!("lookbehind: {:?}", re.find("FOObar"));
20
21    // Atomic group prevents catastrophic backtracking.
22    let re = Regex::new(r"a(?>b*)b").unwrap();
23    println!("atomic find: {:?}", re.find("abbbbc"));
24
25    // Replace with named groups.
26    let re = Regex::new(r"(?P<first>\w+),(?P<second>\w+)").unwrap();
27    println!(
28        "replace: {}",
29        re.replace_all("a,b x,y", "${second} ${first}")
30    );
31
32    // Flags constant.
33    let re = Regex::new_with_flags(r"hello", flags::IGNORECASE | flags::MULTILINE).unwrap();
34    println!("flags: {:x}", re.flags().bits());
35}
Source

pub fn capture_count(&self) -> usize

The number of capturing groups.

Source

pub fn group_names(&self) -> &HashMap<String, usize>

A map from group name to group index.

Source

pub fn group_index(&self, name: &str) -> Option<usize>

Look up a group index by name.

Source

pub fn dump(&self) -> String

Pretty-print the parsed AST (debug aid).

Source

pub fn is_match(&self, haystack: &str) -> bool

Returns true if the pattern matches anywhere in haystack.

Cheaper than find when the match text is not needed — it short-circuits as soon as any match is found.

§Examples
use eregex::Regex;
let re = Regex::new(r"\d+")?;
assert!(re.is_match("abc 123"));
assert!(!re.is_match("no digits here"));
Source

pub fn find<'h>(&self, haystack: &'h str) -> Option<Match<'h>>

Search for the first match, anywhere in haystack. Returns None if there is no match. The returned Match carries the whole-match span and all capture groups.

For end-anchored / partial matching use find_partial.

§Examples
use eregex::Regex;
let re = Regex::new(r"([a-z]+)(\d+)")?;
let m = re.find("x abc42 y").unwrap();
assert_eq!(m.as_str(), "abc42");
assert_eq!(m.start(), 2);
assert_eq!(m.group(2), Some("42"));
Examples found in repository?
examples/demo.rs (line 7)
5fn main() {
6    let re = Regex::new(r"(?P<word>\w+)\s+(?P<num>\d+)").unwrap();
7    let m = re.find("hello 42 world").unwrap();
8    println!("match: {:?}", m.as_str());
9    println!("word = {:?}", m.name("word"));
10    println!("num  = {:?}", m.name("num"));
11
12    // Repeated captures — a signature mrab-regex feature.
13    let re = Regex::new(r"(\w)+").unwrap();
14    let m = re.find("abc").unwrap();
15    println!("captures of group 1: {:?}", m.captures(1));
16
17    // Lookbehind (variable length) + case-insensitive.
18    let re = Regex::new(r"(?i)(?<=foo)bar").unwrap();
19    println!("lookbehind: {:?}", re.find("FOObar"));
20
21    // Atomic group prevents catastrophic backtracking.
22    let re = Regex::new(r"a(?>b*)b").unwrap();
23    println!("atomic find: {:?}", re.find("abbbbc"));
24
25    // Replace with named groups.
26    let re = Regex::new(r"(?P<first>\w+),(?P<second>\w+)").unwrap();
27    println!(
28        "replace: {}",
29        re.replace_all("a,b x,y", "${second} ${first}")
30    );
31
32    // Flags constant.
33    let re = Regex::new_with_flags(r"hello", flags::IGNORECASE | flags::MULTILINE).unwrap();
34    println!("flags: {:x}", re.flags().bits());
35}
More examples
Hide additional examples
examples/gap_match.rs (line 128)
120fn report(name: &str, hay: &str, max_gap: usize) {
121    println!("\n=== {name} ===");
122    println!("haystack: {hay:?}");
123
124    // (1) Show what the bare engine does — both strict and end-anchored partial.
125    let full = Regex::new(FULL).unwrap();
126    println!(
127        "  find         : {:?}",
128        full.find(hay).map(|m| m.as_str().to_string())
129    );
130    println!(
131        "  find_partial : {:?}",
132        match full.find_partial(hay) {
133            None => "None".to_string(),
134            Some(p) => format!("{:?} matched={:?}", p.status, p.matched),
135        }
136    );
137
138    // (2) Gap-tolerant shift-and-resume search.
139    match gap_find(hay, &stm32_segments(), max_gap) {
140        Some(gm) => {
141            println!("  gap_find     : OK");
142            println!("    reconstructed = {:?}", gm.reconstructed);
143            for (label, s, e) in &gm.segments {
144                println!("    segment {label:<8} = [{s}..{e}] {:?}", &hay[*s..*e]);
145            }
146            for (s, e) in &gm.skipped {
147                println!("    skipped        = [{s}..{e}] {:?}", &hay[*s..*e]);
148            }
149
150            // (3) Re-validate the reconstruction with the FULL pattern and
151            //     report clean groups. This is also where `find_partial`
152            //     earns its keep: it confirms Full vs Partial.
153            let p = full
154                .find_partial(&gm.reconstructed)
155                .expect("reconstruction must re-match the full pattern");
156            assert_eq!(p.status, MatchStatus::Full, "reconstruction must be Full");
157            println!(
158                "    groups = [STM32={:?}, F407={:?}, VGT6={:?}]",
159                p.group(1),
160                p.group(2),
161                p.group(3),
162            );
163
164            // The caller asked specifically about #2: group 2 (`F407`) is
165            // assembled from TWO non-contiguous haystack ranges — the `F` at
166            // the tail of segment 1 and the `407` at the head of segment 2.
167            if name.contains("#2") {
168                let (_, _, seg1_end) = gm.segments[0];
169                let (_, seg2_start, _) = gm.segments[1];
170                println!(
171                    "    group F407 split = [{}..{}] + [{}..{}]  (\"F\" + \"407\")",
172                    seg1_end - 1,
173                    seg1_end,
174                    seg2_start,
175                    seg2_start + 3
176                );
177            }
178        }
179        None => println!("  gap_find     : None (NoMatch)"),
180    }
181}
Source

pub fn find_at<'h>(&self, haystack: &'h str, start: usize) -> Option<Match<'h>>

Search for the first match at or after byte offset start.

start is clamped to haystack.len(); it counts bytes, not chars, but may fall in the middle of a UTF-8 sequence only if it lies beyond the haystack end. Useful for resuming a scan after a previous match.

§Examples
use eregex::Regex;
let re = Regex::new(r"\d+")?;
let hay = "a1 b2 c3";
let first = re.find(hay).unwrap();
let next = re.find_at(hay, first.end()).unwrap();
assert_eq!(next.as_str(), "2");
Examples found in repository?
examples/gap_match.rs (line 77)
69fn gap_find(haystack: &str, segments: &[Segment], max_gap: usize) -> Option<GapMatch> {
70    let mut reconstructed = String::new();
71    let mut hits = Vec::with_capacity(segments.len());
72    let mut skipped = Vec::new();
73    let mut cursor = 0usize; // byte offset to search from
74
75    for (i, seg) in segments.iter().enumerate() {
76        // Shift-and-resume: find this segment at or after the cursor.
77        let m = seg.re.find_at(haystack, cursor)?;
78        let (s, e) = (m.start(), m.end());
79        if i > 0 {
80            let gap = s - cursor;
81            if gap > max_gap {
82                return None; // noise too long → NoMatch (#9)
83            }
84            if gap > 0 {
85                skipped.push((cursor, s));
86            }
87        }
88        hits.push((seg.label, s, e));
89        reconstructed.push_str(m.as_str());
90        cursor = e;
91    }
92
93    Some(GapMatch {
94        reconstructed,
95        segments: hits,
96        skipped,
97    })
98}
Source

pub fn captures<'h>(&self, haystack: &'h str) -> Option<Match<'h>>

Like find — included for symmetry with captures_iter.

Source

pub fn match_at_start<'h>(&self, haystack: &'h str) -> Option<Match<'h>>

Require a match anchored at the start of the haystack (like Python’s re.match). The match need not reach the end.

§Examples
use eregex::Regex;
let re = Regex::new(r"\d+")?;
assert_eq!(re.match_at_start("123abc").unwrap().as_str(), "123");
assert!(re.match_at_start("abc123").is_none());
Source

pub fn fullmatch<'h>(&self, haystack: &'h str) -> Option<Match<'h>>

Require a match that covers the entire haystack (Python’s re.fullmatch).

§Examples
use eregex::Regex;
let re = Regex::new(r"\d{3}")?;
assert!(re.fullmatch("123").is_some());
assert!(re.fullmatch("1234").is_none());
Source

pub fn find_iter<'r, 'h>(&'r self, haystack: &'h str) -> FindIter<'r, 'h>

Iterate over non-overlapping matches.

Zero-width matches are yielded once per position and do not loop infinitely: after one, the iterator advances past the next character.

§Examples
use eregex::Regex;
let re = Regex::new(r"\d+")?;
let ms: Vec<_> = re.find_iter("a1 bb 22").map(|m| m.as_str().to_string()).collect();
assert_eq!(ms, vec!["1", "22"]);
Source

pub fn captures_iter<'r, 'h>(&'r self, haystack: &'h str) -> FindIter<'r, 'h>

Iterate over non-overlapping matches (alias of find_iter).

Source

pub fn find_partial<'h>(&self, haystack: &'h str) -> Option<PartialMatch<'h>>

Partial / end-anchored match.

Unlike find, the match must consume the haystack all the way to its end. The result is:

  • None — the input cannot be a prefix of any match (a hard mismatch occurred before end-of-input), or nothing matched at all.
  • Some(Full) — the pattern matched and consumed the entire haystack.
  • Some(Partial) — the pattern consumed the entire haystack but was still asking for more input; in other words, the haystack is a prefix of some full match.

Group state within a PartialMatch distinguishes groups that completed (GroupMatch::Matched) from the group that was entered but not completed (GroupMatch::Partial).

§Examples
use eregex::{MatchStatus, Regex};
let re = Regex::new(r"token=([a-z]+)([0-9]+)")?;

// Incomplete input — more could turn it into a full match.
let p = re.find_partial("x token=abc").unwrap();
assert_eq!(p.status, MatchStatus::Partial);
assert_eq!(p.group(1), Some("abc")); // fully matched
assert_eq!(p.group(2), Some(""));    // entered but empty

// A wrong character rules out any continuation -> no match at all.
assert!(re.find_partial("x token=abc!").is_none());
Examples found in repository?
examples/gap_match.rs (line 132)
120fn report(name: &str, hay: &str, max_gap: usize) {
121    println!("\n=== {name} ===");
122    println!("haystack: {hay:?}");
123
124    // (1) Show what the bare engine does — both strict and end-anchored partial.
125    let full = Regex::new(FULL).unwrap();
126    println!(
127        "  find         : {:?}",
128        full.find(hay).map(|m| m.as_str().to_string())
129    );
130    println!(
131        "  find_partial : {:?}",
132        match full.find_partial(hay) {
133            None => "None".to_string(),
134            Some(p) => format!("{:?} matched={:?}", p.status, p.matched),
135        }
136    );
137
138    // (2) Gap-tolerant shift-and-resume search.
139    match gap_find(hay, &stm32_segments(), max_gap) {
140        Some(gm) => {
141            println!("  gap_find     : OK");
142            println!("    reconstructed = {:?}", gm.reconstructed);
143            for (label, s, e) in &gm.segments {
144                println!("    segment {label:<8} = [{s}..{e}] {:?}", &hay[*s..*e]);
145            }
146            for (s, e) in &gm.skipped {
147                println!("    skipped        = [{s}..{e}] {:?}", &hay[*s..*e]);
148            }
149
150            // (3) Re-validate the reconstruction with the FULL pattern and
151            //     report clean groups. This is also where `find_partial`
152            //     earns its keep: it confirms Full vs Partial.
153            let p = full
154                .find_partial(&gm.reconstructed)
155                .expect("reconstruction must re-match the full pattern");
156            assert_eq!(p.status, MatchStatus::Full, "reconstruction must be Full");
157            println!(
158                "    groups = [STM32={:?}, F407={:?}, VGT6={:?}]",
159                p.group(1),
160                p.group(2),
161                p.group(3),
162            );
163
164            // The caller asked specifically about #2: group 2 (`F407`) is
165            // assembled from TWO non-contiguous haystack ranges — the `F` at
166            // the tail of segment 1 and the `407` at the head of segment 2.
167            if name.contains("#2") {
168                let (_, _, seg1_end) = gm.segments[0];
169                let (_, seg2_start, _) = gm.segments[1];
170                println!(
171                    "    group F407 split = [{}..{}] + [{}..{}]  (\"F\" + \"407\")",
172                    seg1_end - 1,
173                    seg1_end,
174                    seg2_start,
175                    seg2_start + 3
176                );
177            }
178        }
179        None => println!("  gap_find     : None (NoMatch)"),
180    }
181}
182
183fn main() {
184    // #2 / #10 — the main case: real noise between `F` and `407`.
185    // Gap = the " dutyu7 8 " run (≤ 16 bytes), so it is accepted.
186    report(
187        "#2 split by noise (max_gap=16)",
188        "Microcontroller STM32F dutyu7 8 407VGT6   ",
189        16,
190    );
191
192    // #9 — same shape, but max_gap=8 rejects the run.
193    report(
194        "#9 gap too long (max_gap=8)",
195        "Microcontroller STM32F very very very long unrelated text 407VGT6",
196        8,
197    );
198
199    // #7 — a wrong char *inside* the digits segment (`X` where a digit is
200    // expected). No `[0-9]{3}` run exists, so the segment search fails.
201    report(
202        "#7 wrong char inside series",
203        "Microcontroller STM32FX07VGT6",
204        16,
205    );
206
207    // #8 — wrong family (`STM8` instead of `STM32`): the first segment is
208    // never found.
209    report("#8 wrong family", "Microcontroller STM8F407VGT6", 16);
210
211    // #1 — the contiguous happy path: no gap, reconstruction == input tail.
212    report(
213        "#1 contiguous full match",
214        "Microcontroller STM32F407VGT6",
215        16,
216    );
217
218    println!("\n--- end-of-input partials (find_partial alone, no gap mode) ---");
219    let full = Regex::new(FULL).unwrap();
220    for hay in [
221        "Microcontroller STM32F",
222        "Microcontroller STM32F40",
223        "Microcontroller STM32F407VG",
224    ] {
225        let p = full.find_partial(hay).unwrap();
226        println!(
227            "  {:<32} -> {:?} matched={:?} g1={:?} g2={:?} g3={:?}",
228            hay,
229            p.status,
230            p.matched,
231            p.group(1),
232            p.group(2),
233            p.group(3)
234        );
235    }
236
237    println!("\nAll reconstruction checks passed.");
238}
Source

pub fn replace(&self, haystack: &str, repl: &str) -> String

Replace the first match with the expansion of repl.

repl supports $1/${name}/$&/$$ templates (see the module docs for the full syntax). If nothing matches, haystack is returned unchanged.

§Examples
use eregex::Regex;
let re = Regex::new(r"(\w+) (\w+)")?;
assert_eq!(re.replace("hello world", "$2 $1"), "world hello");
Source

pub fn replace_all(&self, haystack: &str, repl: &str) -> String

Replace every non-overlapping match with the expansion of repl.

See replace for the template syntax.

§Examples
use eregex::Regex;
let re = Regex::new(r"(?P<a>\d)(?P<b>\d)")?;
assert_eq!(re.replace_all("12 34", "${b}${a}"), "21 43");
Examples found in repository?
examples/demo.rs (line 29)
5fn main() {
6    let re = Regex::new(r"(?P<word>\w+)\s+(?P<num>\d+)").unwrap();
7    let m = re.find("hello 42 world").unwrap();
8    println!("match: {:?}", m.as_str());
9    println!("word = {:?}", m.name("word"));
10    println!("num  = {:?}", m.name("num"));
11
12    // Repeated captures — a signature mrab-regex feature.
13    let re = Regex::new(r"(\w)+").unwrap();
14    let m = re.find("abc").unwrap();
15    println!("captures of group 1: {:?}", m.captures(1));
16
17    // Lookbehind (variable length) + case-insensitive.
18    let re = Regex::new(r"(?i)(?<=foo)bar").unwrap();
19    println!("lookbehind: {:?}", re.find("FOObar"));
20
21    // Atomic group prevents catastrophic backtracking.
22    let re = Regex::new(r"a(?>b*)b").unwrap();
23    println!("atomic find: {:?}", re.find("abbbbc"));
24
25    // Replace with named groups.
26    let re = Regex::new(r"(?P<first>\w+),(?P<second>\w+)").unwrap();
27    println!(
28        "replace: {}",
29        re.replace_all("a,b x,y", "${second} ${first}")
30    );
31
32    // Flags constant.
33    let re = Regex::new_with_flags(r"hello", flags::IGNORECASE | flags::MULTILINE).unwrap();
34    println!("flags: {:x}", re.flags().bits());
35}
Source

pub fn split(&self, haystack: &str) -> Vec<String>

Split haystack by this pattern, including capturing-group text between parts (matching Python’s re.split semantics).

§Examples
use eregex::Regex;
let re = Regex::new(r"\s+")?;
assert_eq!(re.split("a  b c"), vec!["a", "b", "c"]);
Source

pub fn split_iter<'r, 'h>(&'r self, haystack: &'h str) -> SplitIter<'r, 'h>

An iterator yielding the pieces produced by split.

Trait Implementations§

Source§

impl Debug for Regex

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl Freeze for Regex

§

impl RefUnwindSafe for Regex

§

impl Send for Regex

§

impl Sync for Regex

§

impl Unpin for Regex

§

impl UnsafeUnpin for Regex

§

impl UnwindSafe for Regex

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.