String “我该怎么做?”;解释;字符串中的转义字符?

String “我该怎么做?”;解释;字符串中的转义字符?,string,rust,escaping,String,Rust,Escaping,我想处理一个字符串,该字符串包含一个反斜杠,后跟一个可转义字符,就像它们是一个字符一样 let raw = r#"\""#; let cooked = raw.process_escape_character_magic(); 现在,raw有两个字符:\和“。但我真正想要的是cooked,它只有一个字符:” 如何烹调 我在考虑使用正则表达式,但我觉得应该有更好的方法。我喜欢在Rust中使用迭代器,我认为这是一个完美的用例: #[derive(Debug, PartialEq)] enum My

我想处理一个字符串,该字符串包含一个反斜杠,后跟一个可转义字符,就像它们是一个字符一样

let raw = r#"\""#;
let cooked = raw.process_escape_character_magic();
现在,
raw
有两个字符:
\
。但我真正想要的是
cooked
,它只有一个字符:

如何烹调


我在考虑使用正则表达式,但我觉得应该有更好的方法。

我喜欢在Rust中使用迭代器,我认为这是一个完美的用例:

#[derive(Debug, PartialEq)]
enum MyError {
    EscapeAtEndOfString,
    InvalidEscapedChar(char),
}

struct InterpretEscapedString<'a> {
    s: std::str::Chars<'a>,
}

impl<'a> Iterator for InterpretEscapedString<'a> {
    type Item = Result<char, MyError>;

    fn next(&mut self) -> Option<Self::Item> {
        self.s.next().map(|c| match c {
            '\\' => match self.s.next() {
                None => Err(MyError::EscapeAtEndOfString),
                Some('n') => Ok('\n'),
                Some('\\') => Ok('\\'),
                // etc.
                Some(c) => Err(MyError::InvalidEscapedChar(c)),
            },
            c => Ok(c),
        })
    }
}

fn interpret_escaped_string(s: &str) -> Result<String, MyError> {
    (InterpretEscapedString { s: s.chars() }).collect()
}

fn main() {
    assert_eq!(interpret_escaped_string(r#""#), Ok("".into()));
    assert_eq!(interpret_escaped_string(r#"a"#), Ok("a".into()));
    assert_eq!(interpret_escaped_string(r#"\"#), Err(MyError::EscapeAtEndOfString));
    assert_eq!(interpret_escaped_string(r#"\\"#), Ok("\\".into()));
    assert_eq!(interpret_escaped_string(r#"a\n"#), Ok("a\n".into()));
    assert_eq!(interpret_escaped_string(r#"a\."#), Err(MyError::InvalidEscapedChar('.')));
}
#[派生(调试,部分Q)]
枚举MyError{
逃逸字符串,
InvalidEscapedChar(字符),
}
结构解释器,
}
恳求{
类型项=结果;
fn下一步(&mut self)->选项{
self.s.next().map(| c |匹配c{
'\\'=>匹配self.s.next(){
None=>Err(MyError::EscapeAtEndOfString),
一些('n')=>Ok('\n'),
一些('\')=>Ok('\\'),
//等等。
Some(c)=>Err(MyError::InvalidEscapedChar(c)),
},
c=>正常(c),
})
}
}
fn解释\u转义\u字符串(s:&str)->结果{
(解释器scapedstring{s:s.chars()}).collect()
}
fn main(){
assert_eq!(解释_转义的_字符串(r#“”)、Ok(“.into());
assert_eq!(解释_转义_字符串(r#“a”#),Ok(“a.into());
断言(解释转义字符串(r“\”)、Err(MyError::EscapeAtEndOfString));
断言(解释转义字符串(r“\\”)、Ok(“\\”.into());
assert_eq!(解释_转义_字符串(r#“a\n”#),Ok(“a\n.into());
assert_eq!(解释_转义_字符串(r#“a\”)、Err(MyError::InvalidEscapedChar('.'));
}

这样一个模块的更完整的实现。

字符串中的每个反斜杠+某些字符都应该替换为该字符,还是不同的转义序列意味着不同的事情?(或者,如果您想一次回答一些可以解决很多潜在问题的问题:字符串是从哪里获得的/它是哪种格式?@Ry-与Rust自己的字符串中的含义相同,即,
“\n”
给出了换行符等。无法获取所有转义字符吗?i、 例如,
\“
\”,
\t
\n`,等等?或者我们必须手动将它们放在匹配语句中吗?我想这两种方法都很接近,但仍然会给我留下不好的印象。@kkeey没有理由将它们放在std库中。这是编译器内部的信息。