将字符串解析为整数

标签 parsing rust

所以我试图在字符串中找到一个模式并将其转换为整数。

首先我寻找一个字符串:

let haystack = "HTTP/1.1 200\r\n";
let needle = "HTTP/1.";

let http_location = haystack.rfind(needle);
if (http_location.is_some()) {

现在我已经找到它了,我可以想到两种获取数字状态的方法。要么:

    let mut temp_str = haystack.char_at(http_location.unwrap());
    let status = String::from_str(temp_str);
}

或者:

    let status = String::from_str(&haystack[http_location.unwrap()]);
}

不幸的是,它们都被弃用了(而且可能是错误的)。目前正确的做法是什么?

此外,这部分在风格上是否正确?

let http_location = haystack.rfind(needle);
if (http_location.is_some())

最佳答案

解析是一个广泛而多样的话题。有简单的解析工具,也有高性能的解析工具,并且介于两者之间。

fn main() {
    let haystack = "HTTP/1.1 200\r\n";
    let needle = "HTTP/1.";

    let z: Option<u8> = haystack.rfind(needle).and_then(|pt| {
        let after_match = &haystack[(pt + needle.len())..];
        after_match.splitn(2, " ").next()
    }).and_then(|val| {
        val.parse().ok()
    });

    println!("{:?}", z)
}

在这里,我们像您之前那样使用 rfind,这可能会失败。如果结果是 Some,我们使用 and_then 来运行闭包。第一个闭包在针 之后对字符串进行切片,然后在空格处将其拆分,最多分为 2 个部分。这可能会失败,因此我们使用第二个 and_then 来使用 parse,这可能失败并返回 Result,所以我们将其转换为 Option 以保留类型。

到最后,我们仍然可能失败,因为我们解析的东西可能不是可解析的数字!

Rust 确实可以帮助您明确指出可能会失败的地方,并且您必须处理这些地方。 ^_^

在这种情况下:

  1. 也许字符串没有“HTTP/1”。在里面
  2. 迭代器必须在某个点结束,因此它们可以返回 None
  3. 将字符串解析为数字可能会失败。

这是使用 regex crate 的替代解决方案:

extern crate regex;

use regex::Regex;

fn main() {
    let haystack = "HTTP/1.1 200\r\n";

    let re = Regex::new(r"HTTP/1.(\d) (\d+)\r\n").unwrap();
    let captures = re.captures(haystack).unwrap();
    let version: Option<u8> = captures.at(1).and_then(|version| version.parse().ok());
    let status: Option<u8> = captures.at(2).and_then(|version| version.parse().ok());

    assert_eq!(Some(1), version);
    assert_eq!(Some(200), status);

    println!("Version: {:?}, Status: {:?}", version, status);
}

您会看到我们有相同类型的故障模式,但结构有点不同。

或者可能是使用 Resulttry! 的版本:

#[derive(Debug,Copy,Clone,PartialEq)]
enum Error {
    StartNotFound,
    NotANumber,
}

fn parse_it(haystack: &str) -> Result<u8, Error> {
    let needle = "HTTP/1.";
    let pt = try!(haystack.rfind(needle).ok_or(Error::StartNotFound));
    let after_match = &haystack[(pt + needle.len())..];
    let val = after_match.splitn(2, " ").next().unwrap();
    val.parse().map_err(|_| Error::NotANumber)
}

fn main() {
    println!("{:?}", parse_it("HTTP/1.1 200\r\n"));
    println!("{:?}", parse_it("HTTP/1"));
    println!("{:?}", parse_it("HTTP/1.cow"));
}

关于将字符串解析为整数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30130939/

相关文章:

rust - Rust 结构定义中的最后一个逗号是必要的吗?

generics - 如果我知道这是可能的,我该如何将泛型 T 转换为 f32?

java - Log4j2手动解析?

xml - Go XML - 解析 HTML 中的 bool 属性导致 XML 验证错误

PHP:定义与 HTML 标签兼容的相对路径

rust - 如何在结构中具有可重用的Vec <RwLockReadGuard>以避免分配?

string - [..] 对 Rust 切片意味着什么,它叫什么?

rust - 当 FnBox 闭包无法放入 Arc 时,如何克隆它?

java - 当我在第一个微调器中再次选择一个项目时发生错误,然后相关数据不会在第二个微调器中解析意味着它不会刷新

java - 你如何使用 Java 解析来自 html 的链接?