Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Capture all Regex matches into a vector

Tags:

regex

rust

I'd like to capture all the numbers in a string and return a vector of integers, something like this (the result can be an empty vector):

fn str_strip_numbers(s: &str) -> Vec<isize> {
    unimplemented!()
}

A Python prototype:

def str_strip_numbers(s):
    """
    Returns a vector of integer numbers
    embedded in a string argument.
    """
    return [int(x) for x in re.compile('\d+').findall(s)]

For "alfa" the result is [], for "42by4" it is [42, 4].

What is the idiomatic way to get it in Rust?

UPD:

fn str_strip_numbers(s: &str) -> Vec<String> {
    lazy_static! {
        static ref RE: Regex = Regex::new(r"\d+").unwrap();
    }
    RE.captures(s).and_then(|cap| {cap})
}

I tried something like this, which is grossly wrong on more than one count. What would be the right approach?

like image 783
Alexey Orlov Avatar asked Sep 19 '19 11:09

Alexey Orlov


1 Answers

If you want all of the matches then you probably want to use find_iter(), which gives you an iterator over all of the matches. Then you'll need to convert the string matches into integers, and finally collect the results into a vector.

use lazy_static::lazy_static;
use regex::Regex;

fn str_strip_numbers(s: &str) -> Vec<i64> {
    lazy_static! {
        static ref RE: Regex = Regex::new(r"\d+").unwrap();
    }
    // iterate over all matches
    RE.find_iter(s)
        // try to parse the string matches as i64 (inferred from fn type signature)
        // and filter out the matches that can't be parsed (e.g. if there are too many digits to store in an i64).
        .filter_map(|digits| digits.as_str().parse().ok())
        // collect the results in to a Vec<i64> (inferred from fn type signature)
        .collect()
}
like image 188
Peter Hall Avatar answered Nov 02 '22 00:11

Peter Hall