Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- fn replace_at_idx_in_each_word(line: &str, delims: &[char], idx: usize, replace: char) -> String {
- let mut res = String::with_capacity(line.len());
- for (word, delim) in WordsBy::new(line, delims) {
- replace_nth_and_append(&mut res, word, idx, replace);
- res.extend(delim);
- }
- res
- }
- fn replace_nth_in_each_word(line: &str, delims: &[char], pos: usize, replace: char) -> String {
- assert!(pos != 0, "can not replace zeroth character in word");
- replace_at_idx_in_each_word(line, delims, pos - 1, replace)
- }
- struct WordsBy<'a> {
- line: Option<&'a str>,
- delims: &'a [char],
- }
- impl<'a> WordsBy<'a> {
- fn new(line: &'a str, delims: &'a [char]) -> Self {
- Self {
- line: Some(line),
- delims,
- }
- }
- }
- impl<'a> Iterator for WordsBy<'a> {
- type Item = (&'a str, Option<char>);
- fn next(&mut self) -> Option<Self::Item> {
- let line = self.line.take()?;
- if let Some((pos, delim)) = line.char_indices().find(|(_, c)| self.delims.contains(&c)) {
- let (word, rest) = line.split_at(pos);
- let rest = &rest[delim.len_utf8()..];
- if !rest.is_empty() {
- self.line = Some(rest)
- }
- Some((word, Some(delim)))
- } else {
- Some((line, None))
- }
- }
- }
- fn replace_nth_and_append(acc: &mut String, word: &str, idx: usize, new: char) {
- if let Some((pos, old)) = word.char_indices().nth(idx) {
- let (before, after) = word.split_at(pos);
- acc.push_str(before);
- acc.push(new);
- acc.push_str(&after[old.len_utf8()..])
- } else {
- acc.push_str(word)
- }
- }
- fn main() {
- let line = "Lorem ipsum dolor sit amet, consectetur adipiscing elit.";
- let delims = [' '];
- let result = replace_nth_in_each_word(line, &delims, 2, '%');
- assert_eq!(
- result,
- "L%rem i%sum d%lor s%t a%et, c%nsectetur a%ipiscing e%it."
- );
- }
Add Comment
Please, Sign In to add comment