Конвертировать регулярные выражения в HashMap в Rust?

Вы можете использовать groupby() и max(), чтобы помочь здесь:

from itertools import groupby

with open('toy.txt') as f_input:
    for key, group in groupby(f_input, lambda x: x[:2]):
        print(max(group, key=lambda x: len(x)).strip())

Это отобразится:

ABCDEFGHIJKLMNO
CEST
DBTSFDEO
EOEUDNBNUW
EAEUDNBNUW
FGH

groupby() работает, возвращая список совпадающих элементов на основе функции, в этом случае последовательные строки с теми же первыми двумя символами. Затем функция max() берет этот список и возвращает элемент списка с самой длинной длиной.

3
задан Anders 18 January 2019 в 18:16
поделиться

2 ответа

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

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

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>.
0
ответ дан Shepmaster 18 January 2019 в 18:16
поделиться

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

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
ответ дан Shepmaster 18 January 2019 в 18:16
поделиться
Другие вопросы по тегам:

Похожие вопросы: