将文本文件转换为哈希映射字典



我已经发布了一个与此代码相关的问题,但这似乎是一个不同的问题。我会尽可能清楚地描述这个问题。

我想要实现的目标

使用文本文件(在本例中为/proc/meminfo(中的内容创建一个哈希图,类似于以下格式:

{   
"MemTotal":       "16256760 kB",
"MemFree":          "462276 kB",
"MemAvailable":   "10108672 kB",
"Buffers":         "1432356 kB",
"Cached":          "7138456 kB",
... etc
}

文本文件的原始输出如下所示:

cat /proc/meminfo
MemTotal:       16256760 kB
MemFree:         2685512 kB
MemAvailable:   11105752 kB
Buffers:          774076 kB
Cached:          7722948 kB
... etc

行数应取决于文件包含的行数。

当前情况

我目前拥有的代码将创建一个哈希图:

  • 键:"entryx">
  • value:文本文件中的一行

代码:

fn read_file_to_hashmap(path: impl AsRef<Path>) -> HashMap<String, String> {
let reader = BufReader::new(File::open(path).expect("error here"));
let hashmap = [
"Entry1".to_string(),
"Entry2".to_string(),
"Entry3".to_string(),
"Entry4".to_string(),
"Entry5".to_string(),
]
.into_iter()
.zip(reader.lines().map(Result::unwrap))
.collect::<HashMap<_, _>>();
return hashmap;
}

println!输出:

{
"Entry1": "MemTotal:       16256760 kB",
"Entry5": "Cached:          7138456 kB",
"Entry2": "MemFree:          462276 kB",
"Entry4": "Buffers:         1432356 kB",
"Entry3": "MemAvailable:   10108672 kB",
}

如何更改代码以实现所需目标?

虽然有很多方法可以解决这个问题,但我认为在这种情况下最简单的方法是正则表达式。

在您的情况下,这个正则表达式应该执行您想要的操作:

^(S+):s+(.+)$
  • ^与行的开头匹配(如果启用了multi_line(
  • (S+)匹配一个或多个非空白字符
  • :s+匹配:,后跟至少一个空白字符
  • (.+)匹配所有剩余内容
  • $与行的末尾匹配(如果启用了multi_line(

在程序中编写,如下所示:

use std::collections::HashMap;
use regex::RegexBuilder;
fn main() {
let meminfo_str = std::fs::read_to_string("/proc/meminfo").unwrap();
let re = RegexBuilder::new(r"^(S+):s+(.+)$")
.multi_line(true)
.build()
.unwrap();
let meminfo = re
.captures_iter(&meminfo_str)
.map(|cap| {
(
cap.get(1).unwrap().as_str().to_string(),
cap.get(2).unwrap().as_str().to_string(),
)
})
.collect::<HashMap<_, _>>();
println!("{:#?}", meminfo);
}
{
"SwapTotal": "3145728 kB",
"Slab": "133492 kB",
"SwapFree": "3145728 kB",
"Writeback": "0 kB",
"Mapped": "120212 kB",
"SReclaimable": "99628 kB",
"KernelStack": "7616 kB",
"WritebackTmp": "0 kB",
"VmallocChunk": "0 kB",
"AnonHugePages": "1914880 kB",
"Active(file)": "1187412 kB",
"Mlocked": "0 kB",
"ShmemHugePages": "0 kB",
"FileHugePages": "0 kB",
"MemTotal": "10129324 kB",
"Buffers": "143812 kB",
"HugePages_Total": "0",
"HugePages_Surp": "0",
"DirectMap4k": "68608 kB",
"Inactive(file)": "1245252 kB",
"Inactive": "3928204 kB",
"CommitLimit": "8210388 kB",
"Unevictable": "0 kB",
"AnonPages": "2637672 kB",
"Active(anon)": "448 kB",
"SUnreclaim": "33864 kB",
"MemAvailable": "6891192 kB",
"KReclaimable": "99628 kB",
"Committed_AS": "2777120 kB",
"Hugepagesize": "2048 kB",
"VmallocUsed": "27996 kB",
"SwapCached": "0 kB",
"Active": "1187860 kB",
"HugePages_Rsvd": "0",
"ShmemPmdMapped": "0 kB",
"FilePmdMapped": "0 kB",
"Cached": "2306060 kB",
"VmallocTotal": "34359738367 kB",
"DirectMap2M": "7206912 kB",
"Hugetlb": "0 kB",
"Inactive(anon)": "2682952 kB",
"Dirty": "19460 kB",
"PageTables": "24792 kB",
"Bounce": "0 kB",
"Percpu": "1392 kB",
"Shmem": "17328 kB",
"MemFree": "4633364 kB",
"HugePages_Free": "0",
"DirectMap1G": "12582912 kB",
"NFS_Unstable": "0 kB",
}

如果你想更健壮并正确解析,即使一行的末尾或开头可能有空白,你也可以使用以下正则表达式:

^s*(S+):s+(S.+S)s*$

最新更新