Замена пронумерованных заполнителей на элементы вектора в Rust? - PullRequest
0 голосов
/ 30 декабря 2018

У меня есть следующее:

  • A Vec<&str>.
  • A &str, которые могут содержать $0, $1 и т. Д., Ссылаясь на элементы вvector.

Я хочу получить версию моего &str, в которой все вхождения $i заменены на i-й элемент вектора.Поэтому, если у меня есть vec!["foo", "bar"] и $0$1, результат будет foobar.

Мой первый наивный подход состоял в том, чтобы перебрать i = 1..N и выполнить поиск и замену для каждого индекса.Однако это довольно уродливое и неэффективное решение.Кроме того, он выдает нежелательные выходные данные, если любое из значений в векторе содержит символ $.

Есть ли лучший способ сделать это в Rust?

Ответы [ 2 ]

0 голосов
/ 30 декабря 2018

Это решение вдохновлено (включая скопированные тестовые примеры) Shepmaster's , но упрощает использование метода replace_all.

use regex::{Regex, Captures};

fn template_replace(template: &str, values: &[&str]) -> String {
    let regex = Regex::new(r#"\$(\d+)"#).unwrap();
    regex.replace_all(template, |captures: &Captures| {
        values
            .get(index(captures))
            .unwrap_or(&"")
    }).to_string()
}

fn index(captures: &Captures) -> usize {
    captures.get(1)
        .unwrap()
        .as_str()
        .parse()
        .unwrap()
}

fn main() {
    assert_eq!("ab", template_replace("$0$1", &["a", "b"]));
    assert_eq!("$1b", template_replace("$0$1", &["$1", "b"]));
    assert_eq!("moo", template_replace("moo", &[]));
    assert_eq!("abc", template_replace("a$0b$0c", &[""]));
    assert_eq!("abcde", template_replace("a$0c$1e", &["b", "d"]));
    println!("It works!");
}
0 голосов
/ 30 декабря 2018

Я бы использовал регулярное выражение

use regex::Regex; // 1.1.0

fn example(s: &str, vals: &[&str]) -> String {
    let r = Regex::new(r#"\$(\d+)"#).unwrap();

    let mut start = 0;
    let mut new = String::new();

    for caps in r.captures_iter(s) {
        let m = caps.get(0).expect("Regex group 0 missing");
        let d = caps.get(1).expect("Regex group 1 missing");
        let d: usize = d.as_str().parse().expect("Could not parse index");

        // Copy non-placeholder
        new.push_str(&s[start..m.start()]);
        // Copy placeholder
        new.push_str(&vals[d]);

        start = m.end()
    }

    // Copy non-placeholder
    new.push_str(&s[start..]);

    new
}

fn main() {
    assert_eq!("ab", example("$0$1", &["a", "b"]));
    assert_eq!("$1b", example("$0$1", &["$1", "b"]));
    assert_eq!("moo", example("moo", &[]));
    assert_eq!("abc", example("a$0b$0c", &[""]));
}

См. Также:

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...