rust 我如何解码一个URL并获得作为HashMap的查询字符串?

omtl5h9j  于 2023-01-02  发布在  其他
关注(0)|答案(3)|浏览(211)

我有一个网址是这样的:

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
rekjcdws

rekjcdws1#

其中涉及几个步骤:

  • .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"]));
qzwqbdag

qzwqbdag2#

另一个答案是好的,但我觉得这是应该更直接的东西,所以我把它 Package 在一个函数中:

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://stackoverflow.com?month=May&day=Friday")?;
   let q = query(u);
   println!("{:?}", q);
   Ok(())
}

或者,我找到了另一个板条箱,可以做到这一点:

use auris::URI;

fn main() -> Result<(), auris::ParseError> {
   let s = "http://stackoverflow.com?month=May&day=Friday";
   let u: URI<String> = s.parse()?;
   println!("{:?}", u.qs); // Some({"month": "May", "day": "Friday"})
   Ok(())
}

https://docs.rs/auris

a7qyws3x

a7qyws3x3#

下面是一个解决方案,用于将已经解码的查询字符串从&str解析为HashMap<String, String>,* 仅 * 使用Rust标准库,而不需要外部crate:

use std::collections::HashMap;

fn parse_query(query: &str) -> HashMap<String, String> {
    query
        .split('&')
        .filter_map(|s| {
            s.split_once('=')
                .and_then(|t| Some((t.0.to_owned(), t.1.to_owned())))
        })
        .collect()
}

相关问题