Skip to content

Commit 17d68dc

Browse files
danielparksBurntSushi
authored andcommitted
api: fix for split() not returning last ""
Corrects `/-/.split("a-")` to return `["a", ""]` instead of `["a"]`. (`/-/` is shorthand for `Regex::new("-").unwrap()`.) This adds tests for both `split()` and `splitn()` covering a variety of edge cases. One test is commented out because it is failing due to #521. A future commit will fix it. Note that the `split2` and `split3` tests were passing incorrectly before this change. I have fixed them to expect the correct values. Fixes #627
1 parent aefd58f commit 17d68dc

File tree

7 files changed

+35
-6
lines changed

7 files changed

+35
-6
lines changed

CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ Bug fixes:
1111

1212
* [BUG #594](https://github.com/rust-lang/regex/pull/594):
1313
Improve error reporting when writing `\p\`.
14+
* [BUG #627](https://github.com/rust-lang/regex/issues/627):
15+
Corrects `re.split("a-")` to return `["a", ""]` instead of `["a"]`.
1416
* [BUG #633](https://github.com/rust-lang/regex/pull/633):
1517
Squash deprecation warnings for the `std::error::Error::description` method.
1618

src/re_bytes.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -739,11 +739,11 @@ impl<'r, 't> Iterator for Split<'r, 't> {
739739
let text = self.finder.0.text();
740740
match self.finder.next() {
741741
None => {
742-
if self.last >= text.len() {
742+
if self.last > text.len() {
743743
None
744744
} else {
745745
let s = &text[self.last..];
746-
self.last = text.len();
746+
self.last = text.len() + 1; // Next call will return None
747747
Some(s)
748748
}
749749
}

src/re_unicode.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -779,11 +779,11 @@ impl<'r, 't> Iterator for Split<'r, 't> {
779779
let text = self.finder.0.text();
780780
match self.finder.next() {
781781
None => {
782-
if self.last >= text.len() {
782+
if self.last > text.len() {
783783
None
784784
} else {
785785
let s = &text[self.last..];
786-
self.last = text.len();
786+
self.last = text.len() + 1; // Next call will return None
787787
Some(s)
788788
}
789789
}

tests/api.rs

+16-2
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,20 @@ split!(
205205
split2,
206206
r"(?-u)\b",
207207
"a b c",
208-
&[t!(""), t!("a"), t!(" "), t!("b"), t!(" "), t!("c")]
208+
&[t!(""), t!("a"), t!(" "), t!("b"), t!(" "), t!("c"), t!("")]
209209
);
210-
split!(split3, r"a$", "a", &[t!("")]);
210+
split!(split3, r"a$", "a", &[t!(""), t!("")]);
211+
split!(split_none, r"-", r"a", &[t!("a")]);
212+
split!(split_trailing_blank, r"-", r"a-", &[t!("a"), t!("")]);
213+
split!(split_trailing_blanks, r"-", r"a--", &[t!("a"), t!(""), t!("")]);
214+
split!(split_empty, r"-", r"", &[t!("")]);
215+
216+
// See: https://github.com/rust-lang/regex/issues/521
217+
// splitn!(splitn_below_limit, r"-", r"a", 2, &[t!("a")]);
218+
219+
splitn!(splitn_at_limit, r"-", r"a-b", 2, &[t!("a"), t!("b")]);
220+
splitn!(splitn_above_limit, r"-", r"a-b-c", 2, &[t!("a"), t!("b-c")]);
221+
splitn!(splitn_zero_limit, r"-", r"a-b", 0, empty_vec!());
222+
splitn!(splitn_trailing_blank, r"-", r"a-", 2, &[t!("a"), t!("")]);
223+
splitn!(splitn_trailing_separator, r"-", r"a--", 2, &[t!("a"), t!("-")]);
224+
splitn!(splitn_empty, r"-", r"", 1, &[t!("")]);

tests/macros.rs

+11
Original file line numberDiff line numberDiff line change
@@ -147,3 +147,14 @@ macro_rules! split {
147147
}
148148
}
149149
}
150+
151+
macro_rules! splitn {
152+
($name:ident, $re:expr, $text:expr, $limit:expr, $expected:expr) => {
153+
#[test]
154+
fn $name() {
155+
let re = regex!($re);
156+
let splitted: Vec<_> = re.splitn(t!($text), $limit).collect();
157+
assert_eq!($expected, &*splitted);
158+
}
159+
}
160+
}

tests/macros_bytes.rs

+1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ macro_rules! text { ($text:expr) => { $text.as_bytes() } }
33
macro_rules! t { ($re:expr) => { text!($re) } }
44
macro_rules! match_text { ($text:expr) => { $text.as_bytes() } }
55
macro_rules! use_ { ($($path: tt)*) => { use regex::bytes::$($path)*; } }
6+
macro_rules! empty_vec { () => { <Vec<&[u8]>>::new() } }
67

78
macro_rules! bytes { ($text:expr) => { $text } }
89

tests/macros_str.rs

+1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ macro_rules! text { ($text:expr) => { $text } }
33
macro_rules! t { ($text:expr) => { text!($text) } }
44
macro_rules! match_text { ($text:expr) => { $text.as_str() } }
55
macro_rules! use_ { ($($path: tt)*) => { use regex::$($path)*; } }
6+
macro_rules! empty_vec { () => { <Vec<&str>>::new() } }
67

78
macro_rules! no_expand {
89
($text:expr) => {{

0 commit comments

Comments
 (0)