| 10 | use mz_repr::adt::regex::Regex; |
| 11 | |
| 12 | pub fn regexp_split_to_array<'a>(text: &'a str, regexp: &Regex) -> Vec<&'a str> { |
| 13 | // Postgres regex split handling differs a bit from spec regex split, so we can't use |
| 14 | // regexp.split here. See: https://www.postgresql.org/docs/15/functions-matching.html: |
| 15 | // > the regexp split functions ignore zero-length matches that occur at the start or end |
| 16 | // > of the string or immediately after a previous match |
| 17 | |
| 18 | let mut finder = regexp.find_iter(text); |
| 19 | let mut last = 0; |
| 20 | let mut found = Vec::new(); |
| 21 | loop { |
| 22 | match finder.next() { |
| 23 | None => { |
| 24 | if last <= text.len() { |
| 25 | let s = &text[last..]; |
| 26 | found.push(s); |
| 27 | } |
| 28 | break; |
| 29 | } |
| 30 | Some(m) => { |
| 31 | // Ignore zero length matches at start and end of string. |
| 32 | if m.end() > 0 && m.start() < text.len() { |
| 33 | let matched = &text[last..m.start()]; |
| 34 | last = m.end(); |
| 35 | found.push(matched); |
| 36 | } |
| 37 | } |
| 38 | } |
| 39 | } |
| 40 | found |
| 41 | } |
| 42 | |
| 43 | #[cfg(test)] |
| 44 | mod tests { |