一、绪论
昨天太忙了,没时间写日志,今天早上补一个。昨天把上篇文章遗留的问题解决了(取excel数据无法取多个),其实写出来后,感觉挺简单的,当时也是太晚了没仔细想想。昨天看了一个github上用nom写的一个开源项目(还没看完),是真的坑啊,他写了一个废的方法在那儿,我就堵在那儿堵了一整天(看项目须谨慎),没办法,尽管他很烂我也要坚持给他看完。
二、遗留问题解决
其实很简单,就是把他放到一个集合中,然后将需要的数据都存入到集合中,每次解决完rust的一个问题都会发现也不是想象中那么难(可能确实简单)。
//a="1,"A","1912090231,"B","191209024""
fn test_excel_vec(input:&str)->IResult<&str,Vec<&str>>{
let (input,out)=separated_list0(tag(","),tuple((
key,
tag(","),
tag("\""),
key,
take_until("\""),
tag("\""),
tag(","),
tag("\""),
key,
take_until("\""),
tag("\""),
)))(input)?;
println!("out={:?}",out);//out=[("1", ",", "\"", "A", "", "\"", ",", "\"", "191209023", "", "\""), ("1", ",", "\"", "B", "", "\"", ",", "\"", "191209024", "", "\"")]
let mut value=vec![];
for (id,_,_,k,_,_,_,_,v,_,_) in out{
value.push(id);
value.push(k);
value.push(v);
}
Ok((input,value))
}
#[test]
fn test_extra_excel_vec(){
let input=r#"1,"A","191209023",1,"B","191209024""#;
let (input,val)=test_excel_vec(input).unwrap();
println!("val={:?}",val);//val=["1", "A", "191209023", "1", "B", "191209024"]
}
三、知识点
昨天虽然卡在那儿了,但是也看了写东西
1,解析header,解析的这个也不知道有啥用,但是有个知识点就是里面用到了match,然后解析完成给他放到了一个struct里面,只是一个解析器的用法,所以要掌握。
// 这个方法就是识别是不是WAD2或者WAD3,如果是就转换成对应的枚举型
pub fn parse_wad_magic(i: &[u8]) -> IResult<&[u8], WadMagic> {
let (i, magic) = parse_byte_string(4)(i)?;
let magic = match magic {
"WAD2" => WadMagic::Wad2,
"WAD3" => WadMagic::Wad3,
_ => panic!("Invalid WAD magic"),
};
Ok((i, magic))
}
/// Parse a [`Header`] from a byte slice.
// [*b"WAD2", 10u32.to_le_bytes(), 24u32.to_le_bytes()].concat()
pub fn parse_header(i: &[u8]) -> IResult<&[u8], Header> {
let (i, o) = nom::sequence::tuple((parse_wad_magic, le_u32, le_u32))(i)?;
println!("o={:?}",o);
let (magic, num_entries, dir_offset) = o;
Ok((
i,
Header {
magic,
num_entries,
dir_offset,
},
))
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct Header {
pub magic: WadMagic,
pub num_entries: u32,
pub dir_offset: u32,
}
#[cfg(test)]
mod tests {
use super::*;
use crate::test_data::{test_header_in, test_header_out};
#[test]
fn test_header() {
//let i = test_header_in(); // [*b"WAD2", 10u32.to_le_bytes(), 24u32.to_le_bytes()].concat()
//*b? 20u32.to_le_bytes()?
let i=vec![*b"WAD3", 20u32.to_le_bytes(), 30u32.to_le_bytes()].concat();
let (_, o) = parse_header(&i).unwrap();
fn test_header_out2()->Header{
Header{
magic: WadMagic::Wad3,
num_entries: 20,
dir_offset: 30
}
}
assert_eq!(o, test_header_out2());
}
}
四、小结
这个项目确实写的不太行(注释都没几个),但是他使用解析器解析各种数据的方法值得掌握(我现在就能解析个带标点符号的)。学习别人好的方法,自己加以修正后就能投入使用。