diff --git a/src/re_bytes.rs b/src/re_bytes.rs index c65e3ea1b8..b393dd26d2 100644 --- a/src/re_bytes.rs +++ b/src/re_bytes.rs @@ -494,9 +494,13 @@ impl Regex { mut rep: R, ) -> Cow<'t, [u8]> { if let Some(rep) = rep.no_expansion() { + let mut it = self.find_iter(text).enumerate().peekable(); + if it.peek().is_none() { + return Cow::Borrowed(text); + } let mut new = Vec::with_capacity(text.len()); let mut last_match = 0; - for (i, m) in self.find_iter(text).enumerate() { + for (i, m) in it { if limit > 0 && i >= limit { break } @@ -504,9 +508,6 @@ impl Regex { new.extend_from_slice(&rep); last_match = m.end(); } - if last_match == 0 { - return Cow::Borrowed(text); - } new.extend_from_slice(&text[last_match..]); return Cow::Owned(new); } diff --git a/src/re_unicode.rs b/src/re_unicode.rs index 2d012e64ed..60b0114cb5 100644 --- a/src/re_unicode.rs +++ b/src/re_unicode.rs @@ -583,9 +583,13 @@ impl Regex { // replacements inside the replacement string. We just push it // at each match and be done with it. if let Some(rep) = rep.no_expansion() { + let mut it = self.find_iter(text).enumerate().peekable(); + if it.peek().is_none() { + return Cow::Borrowed(text); + } let mut new = String::with_capacity(text.len()); let mut last_match = 0; - for (i, m) in self.find_iter(text).enumerate() { + for (i, m) in it { if limit > 0 && i >= limit { break } @@ -593,9 +597,6 @@ impl Regex { new.push_str(&rep); last_match = m.end(); } - if last_match == 0 { - return Cow::Borrowed(text); - } new.push_str(&text[last_match..]); return Cow::Owned(new); } diff --git a/tests/replace.rs b/tests/replace.rs index 22eb0c5e57..6e555b93ea 100644 --- a/tests/replace.rs +++ b/tests/replace.rs @@ -36,3 +36,6 @@ replace!(no_expand2, replace, // See https://github.com/rust-lang/regex/issues/314 replace!(match_at_start_replace_with_empty, replace_all, r"foo", "foobar", t!(""), "bar"); + +// See https://github.com/rust-lang/regex/issues/393 +replace!(single_empty_match, replace, r"^", "bar", t!("foo"), "foobar");