如何解码 URL 并将查询字符串作为 HashMap?
How do I decode a URL and get the query string as a HashMap?
我有一个 URL 这样的:
http%3A%2F%2Fexample.com%3Fa%3D1%26b%3D2%26c%3D3
我用 hyper::Url::parse
解析了它并获取了查询字符串:
let parsed_url = hyper::Url::parse(&u).unwrap();
let query_string = parsed_url.query();
但它以字符串形式提供了查询。我想获取 HashMap
形式的查询字符串。像这样:
// some code to convert query string to HashMap
hash_query.get(&"a"); // eq to 1
hash_query.get(&"b"); // eq to 2
涉及几个步骤:
.query_pairs()
方法将为您提供对 Cow<str>
.
对的迭代器
调用 .into_owned()
会给你一个迭代器 String
对。
这是 (String, String)
的迭代器,它正好是 .collect()
到 HashMap<String, String>
的正确形状。
放在一起:
use std::collections::HashMap;
let parsed_url = Url::parse("http://example.com/?a=1&b=2&c=3").unwrap();
let hash_query: HashMap<_, _> = parsed_url.query_pairs().into_owned().collect();
assert_eq!(hash_query.get("a"), "1");
请注意,您需要在 hash_query
上添加类型注释——因为 .collect()
已重载,您必须告诉编译器您想要哪种集合类型。
如果您需要处理重复或重复的键,请尝试 multimap
crate:
use multimap::MultiMap;
let parsed_url = Url::parse("http://example.com/?a=1&a=2&a=3").unwrap();
let hash_query: MultiMap<_, _> = parsed_url.query_pairs().into_owned().collect();
assert_eq!(hash_query.get_vec("a"), Some(&vec!["1", "2", "3"]));
另一个回答不错,但我觉得这个应该更
直截了当,所以我把它包装在一个函数中:
use {
std::collections::HashMap,
url::Url
};
fn query(u: Url) -> HashMap<String, String> {
u.query_pairs().into_owned().collect()
}
fn main() -> Result<(), url::ParseError> {
let u = Url::parse("http://whosebug.com?month=May&day=Friday")?;
let q = query(u);
println!("{:?}", q);
Ok(())
}
或者,我找到了另一个可以为您完成此操作的箱子:
use auris::URI;
fn main() -> Result<(), auris::ParseError> {
let s = "http://whosebug.com?month=May&day=Friday";
let u: URI<String> = s.parse()?;
println!("{:?}", u.qs); // Some({"month": "May", "day": "Friday"})
Ok(())
}
我有一个 URL 这样的:
http%3A%2F%2Fexample.com%3Fa%3D1%26b%3D2%26c%3D3
我用 hyper::Url::parse
解析了它并获取了查询字符串:
let parsed_url = hyper::Url::parse(&u).unwrap();
let query_string = parsed_url.query();
但它以字符串形式提供了查询。我想获取 HashMap
形式的查询字符串。像这样:
// some code to convert query string to HashMap
hash_query.get(&"a"); // eq to 1
hash_query.get(&"b"); // eq to 2
涉及几个步骤:
对的迭代器.query_pairs()
方法将为您提供对Cow<str>
.调用
.into_owned()
会给你一个迭代器String
对。这是
(String, String)
的迭代器,它正好是.collect()
到HashMap<String, String>
的正确形状。
放在一起:
use std::collections::HashMap;
let parsed_url = Url::parse("http://example.com/?a=1&b=2&c=3").unwrap();
let hash_query: HashMap<_, _> = parsed_url.query_pairs().into_owned().collect();
assert_eq!(hash_query.get("a"), "1");
请注意,您需要在 hash_query
上添加类型注释——因为 .collect()
已重载,您必须告诉编译器您想要哪种集合类型。
如果您需要处理重复或重复的键,请尝试 multimap
crate:
use multimap::MultiMap;
let parsed_url = Url::parse("http://example.com/?a=1&a=2&a=3").unwrap();
let hash_query: MultiMap<_, _> = parsed_url.query_pairs().into_owned().collect();
assert_eq!(hash_query.get_vec("a"), Some(&vec!["1", "2", "3"]));
另一个回答不错,但我觉得这个应该更 直截了当,所以我把它包装在一个函数中:
use {
std::collections::HashMap,
url::Url
};
fn query(u: Url) -> HashMap<String, String> {
u.query_pairs().into_owned().collect()
}
fn main() -> Result<(), url::ParseError> {
let u = Url::parse("http://whosebug.com?month=May&day=Friday")?;
let q = query(u);
println!("{:?}", q);
Ok(())
}
或者,我找到了另一个可以为您完成此操作的箱子:
use auris::URI;
fn main() -> Result<(), auris::ParseError> {
let s = "http://whosebug.com?month=May&day=Friday";
let u: URI<String> = s.parse()?;
println!("{:?}", u.qs); // Some({"month": "May", "day": "Friday"})
Ok(())
}