在从用户输入中读取的字符串中解释逃生字符

发布于 2025-02-06 16:09:28 字数 924 浏览 2 评论 0原文

我正在写一个小型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
    }
}

我认为在字符串中添加额外的\将使它被解释为新行,但显然我是错误的。

由于某种原因,如果将字符串传递为参数,则将其解释为没有特殊字符的字符串。
但是,如果字符串被打印为字符串文字,则将\ n符号解释为新行。

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

I am writing a small CLI app in Rust. It processes user input, and if a special escape character is found, it needs to be interpreted.

For example, if user inputs a string 'New\nLine', it should be interpreted as:
New
Line

This is my code so far

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
    }
}

I thought adding an extra \ to the string will make it be interpreted as new line, but I was clearly mistaken.

For some reason if a string in passed as an argument it's interpreted as a string without special characters.
But if string is printed as string literal, then the \n symbol is interpreted as new line.

What am I understanding here wrong, and how to make that \n in a string be interpreted as a new line?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

当爱已成负担 2025-02-13 16:09:29

我认为您误解了字符串文字中如何逃脱。

快速答案是:

  • text在构造字符串错误时已经具有newline字符。我认为您的意思是“ new \\ n”r“ new \ n”
  • 要替换'\''n'用newline字符,请:text = str = str ::替换(&amp; text,“ \\ n”,“ \\ n”, “ \ n”);

背景:字符串文字和逃脱

字符串文字“ new \ nline” dis 包含字符'\''n'\ n是一个字符,\这是一个称为逃脱字符可以创建特殊字符。像newline字符\ n

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

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

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

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

另外,您可以创建一个 不执行逃脱的;含义,您看到的实际上是您得到的:

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

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

因此,如果我们获得了一个用户字符串,那么它肯定会而不是包含\ n字符>字符,而是两个字符\n。因此,让我们使用RAW String R#“ new \ nline”来表示用户输入。

现在,我们可以简单地替换'\''n'字符,带有特殊字符'\ n'

fn main() {
    let s = r#"New\nLine"#;

    let s_unescaped = s.replace("\\n", "\n");

    println!("User input:\n{}\n", s);
    println!("Unescaped:\n{}", s_unescaped);
}
User input:
New\nLine

Unescaped:
New
Line

带有.replace (“ \\ n”,“ \ n”),我们替换字符串“ \\ n”,是字符\ and n,带有“ \ n”,这是newline字符。

当然,代替“ \\ n”我们可以编写原始字符串r“ \ n”

let s_unescaped = s.replace(r"\n", "\n");

附加说明

也引起了很多混乱,这是因为> display{})和debug{:?})打印字符串的方式不同。而{}以其未排列的形式打印(意味着newlines实际上是按线路断开的),而{:?} Escapes 之前的字符串打印它:

fn main() {
    let s = "New\nLine";
    println!("{}", s);
    println!("{:?}", s);

    println!("---");

    let s = "New\\nLine";
    println!("{}", s);
    println!("{:?}", s);
}
New
Line
"New\nLine"
---
New\nLine
"New\\nLine"

I think you misunderstand how escaping in string literals works.

The quick answer is:

  • text already has the newline character in it, as you construct the string wrong. I think you meant "New\\n" or r"New\n".
  • to replace '\' and 'n' with the newline character, do: text = str::replace(&text, "\\n", "\n");.

Background: String literals and escaping

The string literal "New\nLine" does not contain the characters '\' and 'n'. \n is a single character, the \ here is a so called escape character that allows for the creation of special characters. Like the newline character \n:

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

But if the user enters it, it most definitely is the two characters \ and n. To create a string literal that actually contains those two characters, you have to escape the \ as otherwise \n would be interpreted as a single character:

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

Note that the \ character is here shown as \\. In representations that allow escaping, \\ is used for representing an actual \ character.

Alternatively, you could create a raw string literal which does not perform escaping; meaning, what you see is actually what you get:

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

The actual question: interpreting user strings

So if we get a user string, it most certainly does not contain the \n character, but instead the two characters \ and n. So let's use the raw string r#"New\nLine" to represent the user input.

Now we can simply replace the '\' and 'n' characters with the special character '\n':

fn main() {
    let s = r#"New\nLine"#;

    let s_unescaped = s.replace("\\n", "\n");

    println!("User input:\n{}\n", s);
    println!("Unescaped:\n{}", s_unescaped);
}
User input:
New\nLine

Unescaped:
New
Line

With .replace("\\n", "\n"), we replace the string "\\n", which is the characters \ and n, with "\n", which is the newline character.

Of course instead of "\\n" we could write the raw string r"\n":

let s_unescaped = s.replace(r"\n", "\n");

Additional remarks

A lot of confusion also arises from the fact that Display ({}) and Debug ({:?}) print strings differently. While {} prints it in its unescaped form (meaning newlines actually get printed as line breaks), the {:?} escapes the string before printing it:

fn main() {
    let s = "New\nLine";
    println!("{}", s);
    println!("{:?}", s);

    println!("---");

    let s = "New\\nLine";
    println!("{}", s);
    println!("{:?}", s);
}
New
Line
"New\nLine"
---
New\nLine
"New\\nLine"
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文