Replace every match, expanding backreferences in the template. */
(pattern: &str, repl: &str, text: &str)
| 86 | |
| 87 | /* Replace every match, expanding backreferences in the template. */ |
| 88 | pub fn sub(pattern: &str, repl: &str, text: &str) -> Result<String, ReError> { |
| 89 | let re = Regex::compile(pattern)?; |
| 90 | let chars: Vec<char> = text.chars().collect(); |
| 91 | let repl_chars: Vec<char> = repl.chars().collect(); |
| 92 | let m = Matcher::new(&chars, re.prog.flags); |
| 93 | let mut out = String::new(); |
| 94 | let mut last = 0; |
| 95 | let mut start = 0; |
| 96 | while start <= chars.len() { |
| 97 | let Some(c) = m.search_from(&re.prog.root, re.prog.group_count, start) else { |
| 98 | if m.exceeded() { return Err(too_complex()); } |
| 99 | break; |
| 100 | }; |
| 101 | let (s, e) = c[0].unwrap(); |
| 102 | for ch in &chars[last..s] { out.push(*ch); } |
| 103 | expand(&repl_chars, &chars, &c, &re.prog.names, &mut out)?; |
| 104 | if e > s { |
| 105 | last = e; |
| 106 | start = e; |
| 107 | } else { |
| 108 | if e < chars.len() { out.push(chars[e]); } |
| 109 | last = e + 1; |
| 110 | start = e + 1; |
| 111 | } |
| 112 | } |
| 113 | for ch in &chars[last.min(chars.len())..] { out.push(*ch); } |
| 114 | Ok(out) |
| 115 | } |
| 116 | |
| 117 | fn build(chars: &[char], caps: &Caps, ngroups: usize) -> Found { |
| 118 | let (s, e) = caps[0].unwrap(); |
nothing calls this directly
no test coverage detected