Это сложно, потому что регулярное выражение может иметь несколько совпадений, и каждый захват может совпадать несколько раз в одном глобальном совпадении.
Может быть, что-то вроде этого (детская площадка) :
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
. Вы должны сделать следующее:
- Позвоните
capture_names()
, это будет повторяемое число Option<&str>
.
flatten()
итерация, которая удалит None
и развернуть &str
значения.
filter_map()
имена захвата в список кортежей (имя, значение) типа (&str, &str)
. filter
необходим для удаления отсутствующих снимков (благодаря @Anders).
collect()
! Это просто работает, потому что HashMap<K, V>
реализует черту FromIterator<(K, V)>
, поэтому итератор (&str, &str)
собирает в HasMap<&str, &str>
.