diff options
| author | Josh Cotton <jcotton42@outlook.com> | 2021-03-05 11:27:58 -0500 |
|---|---|---|
| committer | Josh Cotton <jcotton42@outlook.com> | 2021-03-05 11:27:58 -0500 |
| commit | a2571cfc8b6f5cf5d8d2e7075ac4809aceae9541 (patch) | |
| tree | f314d496a14b03b818e2594831771d1c35a1b191 /library/alloc/src/string.rs | |
| parent | 8ccc89bc312caa65ca46b55b47492abdd5b6910a (diff) | |
| download | rust-a2571cfc8b6f5cf5d8d2e7075ac4809aceae9541.tar.gz rust-a2571cfc8b6f5cf5d8d2e7075ac4809aceae9541.zip | |
Implement String::remove_matches
Diffstat (limited to 'library/alloc/src/string.rs')
| -rw-r--r-- | library/alloc/src/string.rs | 56 |
1 files changed, 56 insertions, 0 deletions
diff --git a/library/alloc/src/string.rs b/library/alloc/src/string.rs index b567d0a2fe2..45adebf77cb 100644 --- a/library/alloc/src/string.rs +++ b/library/alloc/src/string.rs @@ -1202,6 +1202,62 @@ impl String { ch } + /// Remove all matches of pattern `pat` in the `String`. + /// + /// # Examples + /// + /// ``` + /// #![feature(string_remove_matches)] + /// let mut s = String::from("Trees are not green, the sky is not blue."); + /// s.remove_matches("not "); + /// assert_eq!("Trees are green, the sky is blue.", s); + /// ``` + /// + /// Matches will be detected and removed iteratively, so in cases where + /// patterns overlap, only the first pattern will be removed: + /// + /// ``` + /// #![feature(string_remove_matches)] + /// let mut s = String::from("banana"); + /// s.remove_matches("ana"); + /// assert_eq!("bna", s); + /// ``` + #[unstable(feature = "string_remove_matches", reason = "new API", issue = "72826")] + pub fn remove_matches<'a, P>(&'a mut self, pat: P) + where + P: for<'x> Pattern<'x>, + { + use core::str::pattern::Searcher; + + let matches = { + let mut searcher = pat.into_searcher(self); + let mut matches = Vec::new(); + + while let Some(m) = searcher.next_match() { + matches.push(m); + } + + matches + }; + + let len = self.len(); + let mut shrunk_by = 0; + + // SAFETY: start and end will be on utf8 byte boundaries per + // the Searcher docs + unsafe { + for (start, end) in matches { + ptr::copy( + self.vec.as_mut_ptr().add(end - shrunk_by), + self.vec.as_mut_ptr().add(start - shrunk_by), + len - end, + ); + shrunk_by += end - start; + } + self.vec.set_len(len - shrunk_by); + } + } + /// Retains only the characters specified by the predicate. /// /// In other words, remove all characters `c` such that `f(c)` returns `false`. |
