virchau13
virchau13

Reputation: 1448

How do I parse a float from a string that might contain left-over characters without doing manual parsing?

How do I parse a float from a string that may contain left-over characters, and figure out where it ends, without doing manual parsing (e.g. parseFloat() in JS)?

An example would be the string "2e-1!". I want to evaluate the next float from the string such that I can split this string into "2e-1" and "!" (for example, if I wanted to implement a calculator.) How would I do this without writing a parser to see where the float ends, taking that as an &str, and then using .parse()?

I am aware that this means that I may have to parse nonstandard things such as "3e+1+e3" to 3e+1 (30) and "+e3". This is intended; I do not know all of the ways to format floating point numbers, especially the ones valid to Rust's parse::<f64>(), but I want to handle them regardless.

How can I do this, preferably without external libraries?

Upvotes: 6

Views: 1627

Answers (1)

Sven Marnach
Sven Marnach

Reputation: 602475

As mentioned in the comments, you need to either implement your own floating-point parser or use an external library. The parser in the standard library always errors out when it encounters additional junk in the input string – it doesn't even allow leading or trailing whitespace.

A good external crate to use is nom. It comes with an integrated parser for floating-point numbers that meets your requirements. Examples:

use nom::number::complete::double;
let parser = double::<_, ()>;
assert_eq!(parser("2.0 abc"), Ok((" abc", 2.0)));
let result = parser("Nanananananana hey, Jude!").unwrap();
assert_eq!(result.0, "ananananana hey, Jude!");
assert!(result.1.is_nan());

The parser expects the floating-point number at the very beginning of the string. If you want to allow leading whitespace, you can remove it first using trim_start().

Upvotes: 3

Related Questions