about summary refs log tree commit diff
path: root/src/libcore
diff options
context:
space:
mode:
authorSOFe <sofe2038@gmail.com>2019-11-25 19:36:47 +0800
committerSOFe <sofe2038@gmail.com>2019-11-25 19:36:47 +0800
commit9badc33cda41acadc395f1597947b185f5a9b2a3 (patch)
treeac19330c789fa8faca2d5e511157436d6eab29b8 /src/libcore
parente41ced3f8d8e2f3f377ef931458e612d5f3d1f3f (diff)
downloadrust-9badc33cda41acadc395f1597947b185f5a9b2a3.tar.gz
rust-9badc33cda41acadc395f1597947b185f5a9b2a3.zip
Add str::strip_prefix and str::strip_suffix
Diffstat (limited to 'src/libcore')
-rw-r--r--src/libcore/str/mod.rs69
1 files changed, 68 insertions, 1 deletions
diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs
index 25b7eec5b33..2527aee58cd 100644
--- a/src/libcore/str/mod.rs
+++ b/src/libcore/str/mod.rs
@@ -8,7 +8,7 @@
 #![stable(feature = "rust1", since = "1.0.0")]
 
 use self::pattern::Pattern;
-use self::pattern::{Searcher, ReverseSearcher, DoubleEndedSearcher};
+use self::pattern::{Searcher, SearchStep, ReverseSearcher, DoubleEndedSearcher};
 
 use crate::char;
 use crate::fmt::{self, Write};
@@ -3791,6 +3791,73 @@ impl str {
         }
     }
 
+    /// Returns a string slice with the prefix removed.
+    ///
+    /// If the string starts with the pattern `prefix`, `Some` is returned with the substring where
+    /// the prefix is removed. Unlike `trim_start_matches`, this method removes the prefix exactly
+    /// once.
+    ///
+    /// If the string does not start with `prefix`, it is removed.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(str_strip)]
+    ///
+    /// assert_eq!("foobar".strip_prefix("foo"), Some("bar"));
+    /// assert_eq!("foobar".strip_prefix("bar"), None);
+    /// assert_eq!("foofoo".strip_prefix("foo"), Some("foo"));
+    /// ```
+    #[must_use = "this returns the remaining substring as a new slice, \
+                  without modifying the original"]
+    #[unstable(feature = "str_strip", reason = "newly added", issue = "0")]
+    pub fn strip_prefix<'a, P: Pattern<'a>>(&'a self, prefix: P) -> Option<&'a str> {
+        let mut matcher = prefix.into_searcher(self);
+        if let SearchStep::Match(start, len) = matcher.next() {
+            debug_assert_eq!(start, 0);
+            unsafe {
+                Some(self.get_unchecked(len..))
+            }
+        } else {
+            None
+        }
+    }
+
+    /// Returns a string slice with the suffix removed.
+    ///
+    /// If the string starts with the pattern `suffix`, `Some` is returned with the substring where
+    /// the suffix is removed. Unlike `trim_end_matches`, this method removes the suffix exactly
+    /// once.
+    ///
+    /// If the string does not start with `suffix`, it is removed.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(str_strip)]
+    /// assert_eq!("barfoo".strip_suffix("foo"), Some("bar"));
+    /// assert_eq!("barfoo".strip_suffix("bar"), None);
+    /// assert_eq!("foofoo".strip_suffix("foo"), Some("foo"));
+    /// ```
+    #[must_use = "this returns the remaining substring as a new slice, \
+                  without modifying the original"]
+    #[unstable(feature = "str_strip", reason = "newly added", issue = "0")]
+    pub fn strip_suffix<'a, P>(&'a self, suffix: P) -> Option<&'a str>
+    where
+        P: Pattern<'a>,
+        <P as Pattern<'a>>::Searcher: ReverseSearcher<'a>,
+    {
+        let mut matcher = suffix.into_searcher(self);
+        if let SearchStep::Match(start, end) = matcher.next_back() {
+            debug_assert_eq!(end, self.len());
+            unsafe {
+                Some(self.get_unchecked(..start))
+            }
+        } else {
+            None
+        }
+    }
+
     /// Returns a string slice with all suffixes that match a pattern
     /// repeatedly removed.
     ///