nom总结与实习经历

1.前言

  先bb两句,确实很长时间没有写总结了。主要也是懒,每天下班就不想动了。之所以又开始写文章了,是因为写项目的时候发现之前学过的知识容易遗忘,所以还是把这些知识先记录一下。

2.nom总结

    Rust的nom确实是Rust的强于C/C++的主力之一,他的性能非常快,在单线程的情况下(目前还不会多线程)也能做到几千行的文本在几ms内完成,我目前的学习目标是学习多线程,然后用多线程优化这个项目,到时候我再对比多线程和单线程的性能。

   这里将nom几个常用的解析方法总结一下以免遗忘。

1.tuple(( ))(input)?;

   这是nom最常用的解析方法(除宏外),tuple(( ))作用类似于parse!,是将括号中的内容,按顺序依次解析,其中input是需要被解析的内容。?是Result的语法糖,代表程序默认他为真。tuple中的方法下面会提及,需要注意的是nom返回的是他自己定义的IResult<(),()>类型,返回值就是两个,接收返回值需要进行错误处理(if let unwrap_*()或者等方法 ),注意用 需要该函数返回Result类型。代码示例中用的 _ 表示不需要知道对应方法返回的是什么。

//"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)))
}

2.separated_list0( ( ),( ) )(input)?

   若input函数中是以 "x,y,z" 中间有分隔符的形式存在,即可使用separated_list0()将其按照对应的分割符分开,将数据存放在对应类型的Vec<T>中。

fn parser(s: &str) -> IResult<&str, Vec<&str>> {
  separated_list0(tag("|"), tag("abc"))(s)
}

assert_eq!(parser("abc|abc|abc"), Ok(("", vec!["abc", "abc", "abc"])));

3.opt()(input)?

   在递归解析一个input中的结构时,有一个值可能存在于该结构中,也可能不存在。若都按照存在或者不存在的方法去解析则会导致解析失败。于是nom提供了opt()方法,该方法返回一个Option<T>枚举型,若解析到该值则返回Some(T),反之返回None。

fn parser(i: &str) -> IResult<&str, Option<&str>> {
  opt(alpha1)(i)
}

assert_eq!(parser("abcd;"), Ok((";", Some("abcd"))));
assert_eq!(parser("123;"), Ok(("123;", None)));

4.alt()(input)?

   alt()方法的概念有点类似于opt(),只是opt()是无法确定存不存在该值,而alt()是确定该值存在,但无法确定该值的类型,例如:x 可能是i32 也可能是str ,tuple()无法解析未知类型的数据(当然也有例外,take_until就是一个)。所以nom提供了alt()函数。

fn parser(input: &str) -> IResult<&str, &str> {
  alt((alpha1, digit1))(input)
};
assert_eq!(parser("abc"), Ok(("", "abc")));
assert_eq!(parser("123456"), Ok(("", "123456")));

目前常用的nom解析方法就是这些,下面是解析单个值的方法(说明一下就好了,就不放代码了)

一、multispace0  解析掉该方法前面所有的空格(包括\r ,\n等)

二、tag(  )  代表单个值,例如:tag(" , ")就代表 , 如果tag( )放在tuple( )内就会被解析掉对应里面的         值,... 反正他就代表一个字符。

三、alph0/1 digit0/1   alpha代表字符,0表示单个字符,1表示字符串,digit代表整数,0/1目前没         发现有啥区别,可能是用的比较少(因为他返回的是&str,我把数据解析成&str干什么)。

   

fn parser(input: &str) -> IResult<&str, &str> {
    alpha1(input)
}

assert_eq!(parser("aB1c"), Ok(("1c", "aB")));

四、take_until( )  括号内可以是字符也可以是操作符("\r"),顾名思义就是取到该值为止(不包括该           值),若要将括号内的值一并取掉,可在take_until( )后加一个tag( )。take_while( )用法与之相         反,take_while( )是符合括号内的条件就取,但是二者都没有明确的返回类型,需要上下文推         断。

常用的就这些了,不常用的以后遇见了再加上。

实习总结

  经过了两个月时间的实习,收获还是很多,主要是太忙,没什么时间去学习新知识,连写个博客的时间都没有。实习两个月明确了自己的定位,就是自己这点知识啥也不是,以为自己每天自律得学习就比多半同龄人强,可惜现实确实比我强的人太多了,自己就是那个最弱的。不过实习公司的老板不错,虽然不是手把手教我,但是也是经常教我一些东西(可能是他自己太忙了)。总的来说,这两个月的实习让我明白了自己与其他人的差距,剩下的一年我会尽力去弥补这个缺陷。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值