You probably want to (re-)read the chapter on "Error Handling" in the Rust book. Error handling in Rust is mostly done via the types Result<T, E>
and Option<T>
, both representing an optional value of type T
with Result<T, E>
carrying additional information about the absence of the main value.
You are calling unwrap()
on each Option
or Result
you encounter. unwrap()
is a method saying: "if there is no value of type T
, let the program explode (panic)". You only want to call unwrap()
if an absence of a value is not expected and thus would be a bug! (NB: actually, the unwrap()
in your second line is a perfectly reasonable use!)
But you use unwrap()
incorrectly twice: on the result of captures()
and on the result of get(1)
. Let's tackle captures()
first; it returns an Option<_>
and the docs say:
If no match is found, then None
is returned.
In most cases, the input string not matching the regex is to be expected, thus we should deal with it. We could either just match
the Option
(the standard way to deal with those possible errors, see the Rust book chapter) or we could use Regex::is_match()
before, to check if the string matches.
Next up: get(1)
. Again, the docs tell us:
Returns the match associated with the capture group at index i
. If i
does not correspond to a capture group, or if the capture group did not participate in the match, then None
is returned.
But this time, we don't have to deal with that. Why? Our regex (([0-9]+)
) is constant and we know that the capture group exists and encloses the whole regex. Thus we can rule out both possible situations that would lead to a None
. This means we can unwrap()
, because we don't expect the absence of a value.
The resulting code could look like this:
let input = "abcd123efg";
let re = Regex::new(r"([0-9]+)").unwrap();
match re.captures(e) {
Some(caps) => {
let cap = caps.get(1).unwrap().as_str();
println!("{}", cap);
}
None => {
// The regex did not match. Deal with it here!
}
}