一、緒論
隻是記錄學習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在腦子裡已經有那麼回事了,現在就是逐漸處理更複雜的字元串了。