一、绪论
只是记录学习rust的第一天,不是第一天接触rust。今天看了b站上一个up主讲解nom的视频,我觉得讲得比较好(在为数不多的rust教学视频里),视频两个小时还有一点没看完,里面的内容还是非常扎实的,需要消化一下。
附上视频的地址https://www.bilibili.com/video/BV1UK4y157BP?t=5572,
下面讲解一下今天学的知识。
二、知识点
1.取String类型。这个是最简单的解析,只需要去掉字符串中的引号即可,最后取需要的值就行了
//"a"=x~rust"
fn extra_kv(input:&str)->IResult<&str,(&str,&str)>{
let (input,(_,k,_,_,_,v))=tuple((
tag("\""),
key,
take_until("\""),
tag("\""),
tag("="),
key,
)
)(input)?;
//println!("out:{:?}",out);//("\"", "a", "", "\"", "=", "x")
Ok((input,(k,v)))
}
#[test]
fn test_extra_kv(){
//r# #代表这里面的字符串就是这样,不存在什么转义字符这些
let input=r#""a"=x~rust"#;
let (input,(k,v))=extra_kv(input).unwrap();
assert_eq!("~rust",input);
assert_eq!("a",k);
assert_eq!("x",v);
}
2.取array类型。这个有点低端,当时还不会识别“[”,因为他只有字符串开头和结尾有,无法放到
separated_list0中,下面的代码讲了怎么把"["也消耗掉
fn extra_arr(input:&str)->IResult<&str,Vec<&str>>{
let (input,out)=separated_list0(
//将字符串按逗号分开,然后用tuple处理每个分开后的子串
tag(","),
tuple((
multispace0,
tag("\""),
key,
take_until("\""),
tag("\""),
)),
)(input)?;
//println!("out={:?}",out);//[(" ", "\"", "a", "", "\""), ("", "\"", "b", "", "\""), ("", "\"", "c", "", "\"")]
let mut value=vec![];
for (_,_,v,_,_,) in out{
value.push(v);
}
Ok((input,value))
}
#[test]
fn test_extra_arr(){
let input=r#" "a","b","c" "#;
let (input,values)=extra_arr(input).unwrap();
assert_eq!(vec!["a","b","c"],values);
}
3.取array类型,加强版。其实就是引用了2的代码,然后给他套在tuple中,仔细看能看懂。
//a=["a","b","c"]
fn step_arr(input:&str)->IResult<&str,Vec<&str>>{
let sep=separated_list0(
tag(","),
tuple((
multispace0,
tag("\""),
key,
take_until("\""),
tag("\""),
)),
);
let (input,(_,_,_,values,_,_,_))=tuple((
multispace0,
tag("["),
multispace0,
sep,
multispace0,
tag("]"),
multispace0,
))(input)?;
// println!("out={:?}",values);
//out=("", "[", "", [("", "\"", "x", "", "\""), ("", "\"", "y", "", "\""), ("", "\"", "z", "", "\"")], "", "]", "")
let mut value=vec![];
for (_,_,v,_,_) in values{
value.push(v);
}
Ok((input,value))
}
#[test]
fn test_step_arr(){
let input=r#"["x","y","z"]"#;
let (input,val)=step_arr(input).unwrap();
assert_eq!(vec!["x","y","z"],val);
}
4.混合型。这个就是解决字符串中有可能是数组有可能是String类型的问题,但是字符串中只能存在两种中的一种,还没解决两个类型混合在一起解析,看明天能不能解决吧
fn extra_arr_string(input:&str)->IResult<&str,(&str,Vec<&str>)>{
let (input,(k,_,(arr,obj)))=tuple((//k,_,(arr,obj))
key,
tag("="),
tuple((opt(step_arr),opt(extra_obj))),
))(input)?;
//println!("out={:?}",out);
println!("arr={:?}",arr);
println!("obj={:?}",obj);
let mut value=vec![];
if let Some(a)=arr{
for v in a{
value.push(v);
}
}
if let Some(obj)=obj{
value.push(obj)
}
Ok((input,(" ",value)))
}
#[test]
fn test_extra_arr_string(){
let input=r#"a=["x","y","z"]"#;
let (input,(k,v))=extra_arr_string(input).unwrap();
assert_eq!(vec!["x","y","z"],v);
}
#[test]
fn test_extra_arr_string2(){
let input2=r#"a="x""#;
let (input2,(k,v))=extra_arr_string(input2).unwrap();
assert_eq!(vec!["x"],v);
}
三、小结
学rust这帮人是真的神仙,研究时间复杂度毫秒已经不能满足他们了,已经在思考把程序跑到微秒了,这还是我无法触及的。通过今天视频的学习,nom在脑子里已经有那么回事了,现在就是逐步处理更复杂的字符串了。