@@ -1202,6 +1202,62 @@ impl String {
12021202 ch
12031203 }
12041204
1205+ /// Remove all matches of pattern `pat` in the `String`.
1206+ ///
1207+ /// # Examples
1208+ ///
1209+ /// ```
1210+ /// #![feature(string_remove_matches)]
1211+ /// let mut s = String::from("Trees are not green, the sky is not blue.");
1212+ /// s.remove_matches("not ");
1213+ /// assert_eq!("Trees are green, the sky is blue.", s);
1214+ /// ```
1215+ ///
1216+ /// Matches will be detected and removed iteratively, so in cases where
1217+ /// patterns overlap, only the first pattern will be removed:
1218+ ///
1219+ /// ```
1220+ /// #![feature(string_remove_matches)]
1221+ /// let mut s = String::from("banana");
1222+ /// s.remove_matches("ana");
1223+ /// assert_eq!("bna", s);
1224+ /// ```
1225+ #[ unstable( feature = "string_remove_matches" , reason = "new API" , issue = "72826" ) ]
1226+ pub fn remove_matches < ' a , P > ( & ' a mut self , pat : P )
1227+ where
1228+ P : for < ' x > Pattern < ' x > ,
1229+ {
1230+ use core:: str:: pattern:: Searcher ;
1231+
1232+ let matches = {
1233+ let mut searcher = pat. into_searcher ( self ) ;
1234+ let mut matches = Vec :: new ( ) ;
1235+
1236+ while let Some ( m) = searcher. next_match ( ) {
1237+ matches. push ( m) ;
1238+ }
1239+
1240+ matches
1241+ } ;
1242+
1243+ let len = self . len ( ) ;
1244+ let mut shrunk_by = 0 ;
1245+
1246+ // SAFETY: start and end will be on utf8 byte boundaries per
1247+ // the Searcher docs
1248+ unsafe {
1249+ for ( start, end) in matches {
1250+ ptr:: copy (
1251+ self . vec . as_mut_ptr ( ) . add ( end - shrunk_by) ,
1252+ self . vec . as_mut_ptr ( ) . add ( start - shrunk_by) ,
1253+ len - end,
1254+ ) ;
1255+ shrunk_by += end - start;
1256+ }
1257+ self . vec . set_len ( len - shrunk_by) ;
1258+ }
1259+ }
1260+
12051261 /// Retains only the characters specified by the predicate.
12061262 ///
12071263 /// In other words, remove all characters `c` such that `f(c)` returns `false`.
0 commit comments