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
impl Regex
Sourcepub fn new(pattern: &str) -> Result<Regex>
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?
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
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}Sourcepub fn new_with_flags(pattern: &str, flags: Flags) -> Result<Regex>
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?
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}Sourcepub fn flags(&self) -> Flags
pub fn flags(&self) -> Flags
The resolved flags in effect.
Examples found in repository?
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}Sourcepub fn capture_count(&self) -> usize
pub fn capture_count(&self) -> usize
The number of capturing groups.
Sourcepub fn group_names(&self) -> &HashMap<String, usize>
pub fn group_names(&self) -> &HashMap<String, usize>
A map from group name to group index.
Sourcepub fn group_index(&self, name: &str) -> Option<usize>
pub fn group_index(&self, name: &str) -> Option<usize>
Look up a group index by name.
Sourcepub fn find<'h>(&self, haystack: &'h str) -> Option<Match<'h>>
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?
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
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}Sourcepub fn find_at<'h>(&self, haystack: &'h str, start: usize) -> Option<Match<'h>>
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?
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}Sourcepub fn captures<'h>(&self, haystack: &'h str) -> Option<Match<'h>>
pub fn captures<'h>(&self, haystack: &'h str) -> Option<Match<'h>>
Like find — included for symmetry with captures_iter.
Sourcepub fn match_at_start<'h>(&self, haystack: &'h str) -> Option<Match<'h>>
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());Sourcepub fn fullmatch<'h>(&self, haystack: &'h str) -> Option<Match<'h>>
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());Sourcepub fn find_iter<'r, 'h>(&'r self, haystack: &'h str) -> FindIter<'r, 'h> ⓘ
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"]);Sourcepub fn captures_iter<'r, 'h>(&'r self, haystack: &'h str) -> FindIter<'r, 'h> ⓘ
pub fn captures_iter<'r, 'h>(&'r self, haystack: &'h str) -> FindIter<'r, 'h> ⓘ
Iterate over non-overlapping matches (alias of find_iter).
Sourcepub fn find_partial<'h>(&self, haystack: &'h str) -> Option<PartialMatch<'h>>
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?
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}Sourcepub fn replace(&self, haystack: &str, repl: &str) -> String
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");Sourcepub fn replace_all(&self, haystack: &str, repl: &str) -> String
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?
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}Sourcepub fn split(&self, haystack: &str) -> Vec<String>
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"]);Sourcepub fn split_iter<'r, 'h>(&'r self, haystack: &'h str) -> SplitIter<'r, 'h>
pub fn split_iter<'r, 'h>(&'r self, haystack: &'h str) -> SplitIter<'r, 'h>
An iterator yielding the pieces produced by split.