将字符串解析为整数
Parsing strings into integers
所以我试图在字符串中找到一个模式并将其转换为整数。
首先我寻找一个字符串:
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 确实可以帮助您明确指出可能会失败的地方,并且您必须处理它们。 ^_^
在这种情况下:
- 可能字符串中没有"HTTP/1."
- 迭代器必须在某个点结束,因此它们可以 return
None
.
- 将字符串解析为数字可能会失败。
这是使用 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);
}
你会看到我们有相同类型的故障模式,但结构有点不同。
或者可能是使用 Result
和 try!
的版本:
#[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"));
}
所以我试图在字符串中找到一个模式并将其转换为整数。
首先我寻找一个字符串:
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 确实可以帮助您明确指出可能会失败的地方,并且您必须处理它们。 ^_^
在这种情况下:
- 可能字符串中没有"HTTP/1."
- 迭代器必须在某个点结束,因此它们可以 return
None
. - 将字符串解析为数字可能会失败。
这是使用 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);
}
你会看到我们有相同类型的故障模式,但结构有点不同。
或者可能是使用 Result
和 try!
的版本:
#[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"));
}