解释从用户输入读取的字符串中的转义字符

Lab*_*rat 3 string newline escaping rust

我正在用 Rust 编写一个小型 CLI 应用程序。它处理用户输入,如果发现特殊转义字符,则需要对其进行解释。

例如,如果用户输入一个字符串'New\nLine',它应该被解释为:

这是我到目前为止的代码

fn main() {
    let text: Vec<String> = vec![String::from(r"New\n"), 
                                 String::from(r"Line")];
    slash_parser(text);
}


fn slash_parser(text: Vec<String>) {
    let mut text = text.join(" ");
    println!("{}", text); // ---> New\n Line
    if text.contains("\\") {
        text = str::replace(&text, r"\n", r"\\n");
        println!("{}", text); // ---> New\\n Line
        println!("New\nLine") // ---> New
                              // ---> Line
    }
}
Run Code Online (Sandbox Code Playgroud)

我认为\在字符串中添加一个额外的内容会使其被解释为新行,但我显然错了。

由于某种原因,如果字符串作为参数传递,它将被解释为不带特殊字符的字符串。
但是,如果字符串被打印为字符串文字,则该\n符号将被解释为换行符。

我在这里理解错了什么,以及如何将\n字符串中的它解释为新行?

Fin*_*nis 5

我认为您误解了字符串文字中转义的工作原理。

快速回答是:

  • text由于您构造的字符串错误,其中已经包含换行符。我想你的意思"New\\n"是 或r"New\n"
  • 要将'\'和替换'n'为换行符,请执行:text = str::replace(&text, "\\n", "\n");

背景:字符串文字和转义

字符串文字"New\nLine"包含字符'\''n'\n是单个字符,\这里是所谓的转义字符,允许创建特殊字符。就像换行符一样\n

let s = "New\nLine";
println!("{:?}", s.chars().collect::<Vec<_>>());
println!("{}", s);
Run Code Online (Sandbox Code Playgroud)
['N', 'e', 'w', '\n', 'L', 'i', 'n', 'e']
New
Line
Run Code Online (Sandbox Code Playgroud)

但如果用户输入它,它肯定是\和两个字符n。要创建实际包含这两个字符的字符串文字,您必须转义\否则\n将被解释为单个字符:

['N', 'e', 'w', '\n', 'L', 'i', 'n', 'e']
New
Line
Run Code Online (Sandbox Code Playgroud)
['N', 'e', 'w', '\\', 'n', 'L', 'i', 'n', 'e']
New\nLine
Run Code Online (Sandbox Code Playgroud)

请注意,该\字符此处显示为\\。在允许转义的表示中,\\用于表示实际\字符。

或者,您可以创建一个不执行转义的原始字符串文字;也就是说,所见即所得:

let s = "New\\nLine";
println!("{:?}", s.chars().collect::<Vec<_>>());
println!("{}", s);
Run Code Online (Sandbox Code Playgroud)
['N', 'e', 'w', '\\', 'n', 'L', 'i', 'n', 'e']
New\nLine
Run Code Online (Sandbox Code Playgroud)

实际问题:解释用户字符串

因此,如果我们得到一个用户字符串,它肯定不包含该字符,而是包含和\n两个字符。因此,让我们使用原始字符串来表示用户输入。\nr#"New\nLine"

现在我们可以简单地将'\''n'字符替换为特殊字符'\n'

['N', 'e', 'w', '\\', 'n', 'L', 'i', 'n', 'e']
New\nLine
Run Code Online (Sandbox Code Playgroud)
User input:
New\nLine

Unescaped:
New
Line
Run Code Online (Sandbox Code Playgroud)

使用.replace("\\n", "\n"),我们将字符串"\\n"(即字符)\n, 替换为"\n",即换行符。

当然,"\\n"我们可以写原始字符串r"\n"

let s = r#"New\nLine"#;
println!("{:?}", s.chars().collect::<Vec<_>>());
println!("{}", s);
Run Code Online (Sandbox Code Playgroud)

补充说明

Display( {}) 和Debug( ) 打印字符串的方式不同,这也引起了很多混乱{:?}。虽然{}以未转义的形式打印它(意味着换行符实际上被打印为换行符),但在打印之前会对字符串{:?} 进行转义:

['N', 'e', 'w', '\\', 'n', 'L', 'i', 'n', 'e']
New\nLine
Run Code Online (Sandbox Code Playgroud)
New
Line
"New\nLine"
---
New\nLine
"New\\nLine"
Run Code Online (Sandbox Code Playgroud)