mirror of
https://github.com/openharmony/third_party_rust_regex.git
synced 2026-06-30 21:37:57 -04:00
impl: optimize replacen loop
The previous implementation didn't bail out of the replace loop when the limit was reached until one more than the total number of 'find' operations had completed. By moving the limit check to the end of the loop body, we execute only the number of 'find' operations that is necessary, instead of one extra. This optimization only applies to 'replacen' calls with a limit not equal to '0'. That includes 'replace' but not 'replace_all'. PR #930
This commit is contained in:
+6
-6
@@ -496,12 +496,12 @@ impl Regex {
|
||||
let mut new = Vec::with_capacity(text.len());
|
||||
let mut last_match = 0;
|
||||
for (i, m) in it {
|
||||
if limit > 0 && i >= limit {
|
||||
break;
|
||||
}
|
||||
new.extend_from_slice(&text[last_match..m.start()]);
|
||||
new.extend_from_slice(&rep);
|
||||
last_match = m.end();
|
||||
if limit > 0 && i >= limit - 1 {
|
||||
break;
|
||||
}
|
||||
}
|
||||
new.extend_from_slice(&text[last_match..]);
|
||||
return Cow::Owned(new);
|
||||
@@ -516,14 +516,14 @@ impl Regex {
|
||||
let mut new = Vec::with_capacity(text.len());
|
||||
let mut last_match = 0;
|
||||
for (i, cap) in it {
|
||||
if limit > 0 && i >= limit {
|
||||
break;
|
||||
}
|
||||
// unwrap on 0 is OK because captures only reports matches
|
||||
let m = cap.get(0).unwrap();
|
||||
new.extend_from_slice(&text[last_match..m.start()]);
|
||||
rep.replace_append(&cap, &mut new);
|
||||
last_match = m.end();
|
||||
if limit > 0 && i >= limit - 1 {
|
||||
break;
|
||||
}
|
||||
}
|
||||
new.extend_from_slice(&text[last_match..]);
|
||||
Cow::Owned(new)
|
||||
|
||||
+6
-6
@@ -554,12 +554,12 @@ impl Regex {
|
||||
let mut new = String::with_capacity(text.len());
|
||||
let mut last_match = 0;
|
||||
for (i, m) in it {
|
||||
if limit > 0 && i >= limit {
|
||||
break;
|
||||
}
|
||||
new.push_str(&text[last_match..m.start()]);
|
||||
new.push_str(&rep);
|
||||
last_match = m.end();
|
||||
if limit > 0 && i >= limit - 1 {
|
||||
break;
|
||||
}
|
||||
}
|
||||
new.push_str(&text[last_match..]);
|
||||
return Cow::Owned(new);
|
||||
@@ -574,14 +574,14 @@ impl Regex {
|
||||
let mut new = String::with_capacity(text.len());
|
||||
let mut last_match = 0;
|
||||
for (i, cap) in it {
|
||||
if limit > 0 && i >= limit {
|
||||
break;
|
||||
}
|
||||
// unwrap on 0 is OK because captures only reports matches
|
||||
let m = cap.get(0).unwrap();
|
||||
new.push_str(&text[last_match..m.start()]);
|
||||
rep.replace_append(&cap, &mut new);
|
||||
last_match = m.end();
|
||||
if limit > 0 && i >= limit - 1 {
|
||||
break;
|
||||
}
|
||||
}
|
||||
new.push_str(&text[last_match..]);
|
||||
Cow::Owned(new)
|
||||
|
||||
@@ -228,3 +228,21 @@ replace!(
|
||||
bytes!(&std::borrow::Cow::<'_, [u8]>::Owned(vec![b'Z'])),
|
||||
"age: Z6"
|
||||
);
|
||||
|
||||
#[test]
|
||||
fn replacen_no_captures() {
|
||||
let re = regex!(r"[0-9]");
|
||||
assert_eq!(
|
||||
re.replacen(text!("age: 1234"), 2, t!("Z")),
|
||||
text!("age: ZZ34")
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn replacen_with_captures() {
|
||||
let re = regex!(r"([0-9])");
|
||||
assert_eq!(
|
||||
re.replacen(text!("age: 1234"), 2, t!("${1}Z")),
|
||||
text!("age: 1Z2Z34")
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user