parent
6a5148bda1
commit
c6ca2205ea
3 changed files with 59 additions and 39 deletions
|
@ -727,23 +727,20 @@ impl str {
|
|||
core_str::StrExt::rsplit(&self[..], pat)
|
||||
}
|
||||
|
||||
/// An iterator over substrings of `self`, separated by characters matched by a pattern,
|
||||
/// starting from the end of the string.
|
||||
///
|
||||
/// Restricted to splitting at most `count` times.
|
||||
///
|
||||
/// The pattern can be a simple `&str`, or a closure that determines the split.
|
||||
/// An iterator over substrings of `self`, separated by a pattern,
|
||||
/// starting from the end of the string, restricted to splitting
|
||||
/// at most `count` times.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Simple `&str` patterns:
|
||||
/// Simple patterns:
|
||||
///
|
||||
/// ```
|
||||
/// let v: Vec<&str> = "Mary had a little lamb".rsplitn(2, ' ').collect();
|
||||
/// assert_eq!(v, ["lamb", "little", "Mary had a"]);
|
||||
///
|
||||
/// let v: Vec<&str> = "lionXXtigerXleopard".rsplitn(2, 'X').collect();
|
||||
/// assert_eq!(v, ["leopard", "tiger", "lionX"]);
|
||||
/// let v: Vec<&str> = "lion::tiger::leopard".rsplitn(1, "::").collect();
|
||||
/// assert_eq!(v, ["leopard", "lion::tiger"]);
|
||||
/// ```
|
||||
///
|
||||
/// More complex patterns with a lambda:
|
||||
|
@ -753,7 +750,9 @@ impl str {
|
|||
/// assert_eq!(v, ["ghi", "abc1def"]);
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn rsplitn<'a, P: Pattern<'a>>(&'a self, count: usize, pat: P) -> RSplitN<'a, P> {
|
||||
pub fn rsplitn<'a, P: Pattern<'a>>(&'a self, count: usize, pat: P) -> RSplitN<'a, P>
|
||||
where P::Searcher: ReverseSearcher<'a>
|
||||
{
|
||||
core_str::StrExt::rsplitn(&self[..], count, pat)
|
||||
}
|
||||
|
||||
|
|
|
@ -924,6 +924,20 @@ fn test_rsplit() {
|
|||
assert_eq!(split, ["mb\n", "mb\nLittle l", " little l", "d ", "ry h", "\nM"]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rsplitn() {
|
||||
let data = "\nMäry häd ä little lämb\nLittle lämb\n";
|
||||
|
||||
let split: Vec<&str> = data.rsplitn(1, ' ').collect();
|
||||
assert_eq!(split, ["lämb\n", "\nMäry häd ä little lämb\nLittle"]);
|
||||
|
||||
let split: Vec<&str> = data.rsplitn(1, "lämb").collect();
|
||||
assert_eq!(split, ["\n", "\nMäry häd ä little lämb\nLittle "]);
|
||||
|
||||
let split: Vec<&str> = data.rsplitn(1, |c: char| c == 'ä').collect();
|
||||
assert_eq!(split, ["mb\n", "\nMäry häd ä little lämb\nLittle l"]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_words() {
|
||||
let data = "\n \tMäry häd\tä little lämb\nLittle lämb\n";
|
||||
|
|
|
@ -567,7 +567,6 @@ struct CharSplitsN<'a, P: Pattern<'a>> {
|
|||
iter: CharSplits<'a, P>,
|
||||
/// The number of splits remaining
|
||||
count: usize,
|
||||
invert: bool,
|
||||
}
|
||||
|
||||
/// An iterator over the substrings of a string, separated by a
|
||||
|
@ -582,6 +581,13 @@ struct RCharSplits<'a, P: Pattern<'a>> {
|
|||
finished: bool,
|
||||
}
|
||||
|
||||
/// An iterator over the substrings of a string, separated by a
|
||||
/// pattern, splitting at most `count` times, in reverse order.
|
||||
struct RCharSplitsN<'a, P: Pattern<'a>> {
|
||||
iter: RCharSplits<'a, P>,
|
||||
/// The number of splits remaining
|
||||
count: usize,
|
||||
}
|
||||
|
||||
/// An iterator over the lines of a string, separated by `\n`.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
|
@ -661,15 +667,14 @@ where P::Searcher: DoubleEndedSearcher<'a> {
|
|||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<'a, P: Pattern<'a>> Iterator for CharSplitsN<'a, P>
|
||||
where P::Searcher: DoubleEndedSearcher<'a> {
|
||||
impl<'a, P: Pattern<'a>> Iterator for CharSplitsN<'a, P> {
|
||||
type Item = &'a str;
|
||||
|
||||
#[inline]
|
||||
fn next(&mut self) -> Option<&'a str> {
|
||||
if self.count != 0 {
|
||||
self.count -= 1;
|
||||
if self.invert { self.iter.next_back() } else { self.iter.next() }
|
||||
self.iter.next()
|
||||
} else {
|
||||
self.iter.get_end()
|
||||
}
|
||||
|
@ -713,6 +718,23 @@ impl<'a, P: Pattern<'a>> Iterator for RCharSplits<'a, P>
|
|||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<'a, P: Pattern<'a>> Iterator for RCharSplitsN<'a, P>
|
||||
where P::Searcher: ReverseSearcher<'a>
|
||||
{
|
||||
type Item = &'a str;
|
||||
|
||||
#[inline]
|
||||
fn next(&mut self) -> Option<&'a str> {
|
||||
if self.count != 0 {
|
||||
self.count -= 1;
|
||||
self.iter.next()
|
||||
} else {
|
||||
self.iter.get_remainder()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// The internal state of an iterator that searches for matches of a substring
|
||||
/// within a larger string using two-way search
|
||||
#[derive(Clone)]
|
||||
|
@ -1360,23 +1382,7 @@ impl<'a, S: ?Sized> Str for &'a S where S: Str {
|
|||
/// Return type of `StrExt::split`
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub struct Split<'a, P: Pattern<'a>>(CharSplits<'a, P>);
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<'a, P: Pattern<'a>> Iterator for Split<'a, P> {
|
||||
type Item = &'a str;
|
||||
|
||||
#[inline]
|
||||
fn next(&mut self) -> Option<&'a str> {
|
||||
self.0.next()
|
||||
}
|
||||
}
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<'a, P: Pattern<'a>> DoubleEndedIterator for Split<'a, P>
|
||||
where P::Searcher: DoubleEndedSearcher<'a> {
|
||||
#[inline]
|
||||
fn next_back(&mut self) -> Option<&'a str> {
|
||||
self.0.next_back()
|
||||
}
|
||||
}
|
||||
delegate_iter!{pattern &'a str : Split<'a, P>}
|
||||
|
||||
/// Return type of `StrExt::split_terminator`
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
|
@ -1395,8 +1401,8 @@ delegate_iter!{pattern reverse &'a str : RSplit<'a, P>}
|
|||
|
||||
/// Return type of `StrExt::rsplitn`
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub struct RSplitN<'a, P: Pattern<'a>>(CharSplitsN<'a, P>);
|
||||
delegate_iter!{pattern forward &'a str : RSplitN<'a, P>}
|
||||
pub struct RSplitN<'a, P: Pattern<'a>>(RCharSplitsN<'a, P>);
|
||||
delegate_iter!{pattern reverse &'a str : RSplitN<'a, P>}
|
||||
|
||||
/// Methods for string slices
|
||||
#[allow(missing_docs)]
|
||||
|
@ -1414,7 +1420,8 @@ pub trait StrExt {
|
|||
fn split_terminator<'a, P: Pattern<'a>>(&'a self, pat: P) -> SplitTerminator<'a, P>;
|
||||
fn rsplit<'a, P: Pattern<'a>>(&'a self, pat: P) -> RSplit<'a, P>
|
||||
where P::Searcher: ReverseSearcher<'a>;
|
||||
fn rsplitn<'a, P: Pattern<'a>>(&'a self, count: usize, pat: P) -> RSplitN<'a, P>;
|
||||
fn rsplitn<'a, P: Pattern<'a>>(&'a self, count: usize, pat: P) -> RSplitN<'a, P>
|
||||
where P::Searcher: ReverseSearcher<'a>;
|
||||
fn match_indices<'a, P: Pattern<'a>>(&'a self, pat: P) -> MatchIndices<'a, P>;
|
||||
#[allow(deprecated) /* for SplitStr */]
|
||||
fn split_str<'a, P: Pattern<'a>>(&'a self, pat: P) -> SplitStr<'a, P>;
|
||||
|
@ -1498,7 +1505,6 @@ impl StrExt for str {
|
|||
SplitN(CharSplitsN {
|
||||
iter: self.split(pat).0,
|
||||
count: count,
|
||||
invert: false,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -1524,11 +1530,12 @@ impl StrExt for str {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
fn rsplitn<'a, P: Pattern<'a>>(&'a self, count: usize, pat: P) -> RSplitN<'a, P> {
|
||||
RSplitN(CharSplitsN {
|
||||
iter: self.split(pat).0,
|
||||
fn rsplitn<'a, P: Pattern<'a>>(&'a self, count: usize, pat: P) -> RSplitN<'a, P>
|
||||
where P::Searcher: ReverseSearcher<'a>
|
||||
{
|
||||
RSplitN(RCharSplitsN {
|
||||
iter: self.rsplit(pat).0,
|
||||
count: count,
|
||||
invert: true,
|
||||
})
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue