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库中。这是编译器内部的信息。