Parsing 如何使用nom精确匹配一个字节?

Parsing 如何使用nom精确匹配一个字节?,parsing,rust,nom,Parsing,Rust,Nom,我想将一个字母字符(a-zA-Z)与nom完全匹配 我知道我可以用take__使用类似以下内容: // match one or more alphabetical characters pub fn alpha_many(input: &[u8]) -> IResult<&[u8], &[u8]> { take_while!(input, |c| { (c >= 0x41 && c <= 0x5a)

我想将一个字母字符(
a-zA-Z
)与nom完全匹配

我知道我可以用
take__使用类似以下内容:

// match one or more alphabetical characters
pub fn alpha_many(input: &[u8]) -> IResult<&[u8], &[u8]> {
    take_while!(input, |c| {
        (c >= 0x41 && c <= 0x5a) || (c >= 0x61 && c <= 0x7a)
    })
}

我想到了这个。如果没有人提出更好的解决方案,我明天会将此标记为公认的答案:

use nom::{self, ErrorKind, IResult, Needed};

/// Alphabetical characters ([RFC5234 appendix B.1])
///
/// [RFC5234 appendix B.1]: https://tools.ietf.org/html/rfc5234#appendix-B.1
///
/// ```no_rust
/// ALPHA          =  %x41-5A / %x61-7A   ; A-Z / a-z
/// ```
pub struct Alpha;

impl Alpha {
    /// Return true if the given byte represents an alphabetical character
    pub fn is_alpha(c: u8) -> bool {
        (c >= 0x41 && c <= 0x5a) || (c >= 0x61 && c <= 0x7a)
    }

    /// Parse one or more alphabetical characters
    pub fn parse_many(input: &[u8]) -> IResult<&[u8], &[u8]> {
        take_while!(input, Self::is_alpha)
    }

    /// Parse one alphabetical character
    pub fn parse_one(input: &[u8]) -> IResult<&[u8], u8> {
        Self::parse_n(input, 1).map(|res| res[0])
    }

    /// Parse n alphabetical characters
    pub fn parse_n(input: &[u8], n: usize) -> IResult<&[u8], &[u8]> {
        Self::parse_m_n(input, n, n)
    }

    /// Parse between m and n alphabetical characters
    pub fn parse_m_n(input: &[u8], m: usize, n: usize) -> IResult<&[u8], &[u8]> {
        if input.len() < m {
            return IResult::Incomplete(Needed::Size(input.len() - m));
        }
        for i in 0..n {
            if !Self::is_alpha(input[i]) {
                // We were supposed to have at least m printable bytes
                if i < m {
                    return IResult::Error(error_position!(ErrorKind::ManyMN, &input[..]));
                } else {
                    return IResult::Done(&input[i..], &input[0..i]);
                }
            }
        }
        return IResult::Done(&input[n..], &input[0..n]);
    }
}
使用nom:{self,ErrorKind,IResult,Needed};
///字母字符([RFC5234附录B.1])
///
///[RFC5234附录B.1]:https://tools.ietf.org/html/rfc5234#appendix-B.1
///
///“不生锈
///α=%x41-5A/%x61-7A;A-Z/A-Z
/// ```
pub-struct-Alpha;
implα{
///如果给定字节表示字母字符,则返回true
pub fn是_alpha(c:u8)->bool{
(c>=0x41&&c=0x61&&c IResult{
等待!(输入,Self::is_alpha)
}
///解析一个字母字符
pub fn parse_one(输入:&[u8])->IResult{
Self::parse_n(输入,1).map(| res | res[0])
}
///解析n个字母字符
pub fn parse_n(输入:&[u8],n:usize)->IResult{
Self::parse_m_n(输入,n,n)
}
///解析m和n个字母字符
pub fn parse_m_n(输入:&[u8],m:usize,n:usize)->IResult{
如果输入.len()
如果您将其中一个传递给
count!
并将1作为count的匹配长度,会发生什么情况?这不应该是
返回IResult::Complete(Required::Size(m-input.len());
?否则,它似乎总是处于下溢和恐慌状态。
use nom::{self, ErrorKind, IResult, Needed};

/// Alphabetical characters ([RFC5234 appendix B.1])
///
/// [RFC5234 appendix B.1]: https://tools.ietf.org/html/rfc5234#appendix-B.1
///
/// ```no_rust
/// ALPHA          =  %x41-5A / %x61-7A   ; A-Z / a-z
/// ```
pub struct Alpha;

impl Alpha {
    /// Return true if the given byte represents an alphabetical character
    pub fn is_alpha(c: u8) -> bool {
        (c >= 0x41 && c <= 0x5a) || (c >= 0x61 && c <= 0x7a)
    }

    /// Parse one or more alphabetical characters
    pub fn parse_many(input: &[u8]) -> IResult<&[u8], &[u8]> {
        take_while!(input, Self::is_alpha)
    }

    /// Parse one alphabetical character
    pub fn parse_one(input: &[u8]) -> IResult<&[u8], u8> {
        Self::parse_n(input, 1).map(|res| res[0])
    }

    /// Parse n alphabetical characters
    pub fn parse_n(input: &[u8], n: usize) -> IResult<&[u8], &[u8]> {
        Self::parse_m_n(input, n, n)
    }

    /// Parse between m and n alphabetical characters
    pub fn parse_m_n(input: &[u8], m: usize, n: usize) -> IResult<&[u8], &[u8]> {
        if input.len() < m {
            return IResult::Incomplete(Needed::Size(input.len() - m));
        }
        for i in 0..n {
            if !Self::is_alpha(input[i]) {
                // We were supposed to have at least m printable bytes
                if i < m {
                    return IResult::Error(error_position!(ErrorKind::ManyMN, &input[..]));
                } else {
                    return IResult::Done(&input[i..], &input[0..i]);
                }
            }
        }
        return IResult::Done(&input[n..], &input[0..n]);
    }
}