Rust has a lot of idiomatic approaches to common things, like Iterator::enumerate or str::char_indices to iterate over both the index and the element(char in str).
Similarly replace_with(not limited to just strs) could be used to replace a pattern with the result of a closure, like so:
let str = "{}, {}!";
let new_str = str.replace_with("{}", |i| if i == 0 {
i += 1;
"Hello"
} else {
"World"
);
So you don't need to write verbose for loops.
In the str, it could be declared as:
pub fn replace_with<P, F>(&self, pattern: P, closure: F) -> &str
where
P: Pattern,
F: FnMut(usize /* position of pattern */, P /* actual pattern (if there are multiple and you want to check which one is) */) -> &str {}
Where if an iterator implementation is included, the pattern in the closure would not be needed, and a slice of Iterator::Items could be used instead of just one, so that you can provide different code for different patterns.
It looks like this would essentially duplicate a less powerful subset of Regex::replace(), so given that the latter exists, I don't see why this should be in std.