Конвертировать регулярные выражения в HashMap в Rust? - PullRequest
0 голосов
/ 18 января 2019

У меня есть Regex с неизвестным количеством именованных групп с неизвестными именами. Я хочу сопоставить строку с этим регулярным выражением и получить HashMap<&str, &str> с именем группы в качестве ключа и захваченными строками в качестве значения.

Как я могу это сделать? Придется ли мне использовать regex.captures(str).iter(), а затем каким-то образом отобразить, отфильтровать и собрать в карту? Или есть какой-нибудь ярлык?

Ответы [ 2 ]

0 голосов
/ 18 января 2019

Если у вас есть несколько снимков, вы можете собрать их в список следующим образом:

let all: Vec<HashMap<&str, &str>> = re
    .captures_iter("2012-01-12 , 2013-07-11 , 2014-09-14")
    .map(|caps| {
        re.capture_names()
            .map(|o| o.and_then(|n| Some((n, caps.name(n)?.as_str()))))
            .flatten()
            .collect()
    })
    .collect();

println!("{:#?}", all);
0 голосов
/ 18 января 2019

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

Может быть, что-то вроде этого (детская площадка) :

fn main() {
    let re = Regex::new(r"(?P<y>\d{4})-(?P<m>\d{2})-(?P<d>\d{2})").unwrap();
    let text = "2012-03-14";
    let caps = re.captures(text).unwrap();
    let dict: HashMap<&str, &str> = re
        .capture_names()
        .flatten()
        .filter_map(|n| Some((n, caps.name(n)?.as_str())))
        .collect();
    println!("{:#?}", dict);
}

Это выводит:

{
    "y": "2012",
    "d": "14",
    "m": "03"
}

Код становится простым, когда вы понимаете, что имена перехвата доступны не из самого Match, а из родительского Regex. Вы должны сделать следующее:

  1. Позвоните capture_names(), это будет повторяемое число Option<&str>.
  2. flatten() итерация, которая удалит None и развернуть &str значения.
  3. filter_map() имена захвата в список кортежей (имя, значение) типа (&str, &str). filter необходим для удаления отсутствующих снимков (благодаря @Anders).
  4. collect()! Это просто работает, потому что HashMap<K, V> реализует черту FromIterator<(K, V)>, поэтому итератор (&str, &str) собирает в HasMap<&str, &str>.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...