Go语言中的”\n”和换行符有什么区别?

huangapple go评论83阅读模式
英文:

Go lang differentiate "\n" and line break

问题

我正在尝试通过以下代码读取由Linux命令生成的特定字符串输出:

out, err := exec.Command("sh", "-c", cmd).Output()

上述的out[]byte类型的,我该如何区分行内容中包含的"\n"字符和真正的换行符?我尝试了以下方法:

strings.Split(output, "\n")

bufio.NewScanner(strings.NewReader(output))

但是它们都会在遇到"\n"字符时将整个字符串缓冲区拆分开来。

好的,为了澄清,"unreal"的换行是指包含在字符串中的"\n"字符,如下所示:

打印第一个结果"123;\n234;\n"
打印第二个结果"456;\n"

整个输出是一个大的多行字符串,它还可能包含其他带引号的字符串,我正在我的Go程序中处理整个字符串输出,但我无法控制命令输出并在"\n"字符之前添加反斜杠。

进一步澄清:我想处理包含字符串的字节序列,并希望保留内部字符串中包含的"\n",并使用外层的"\n"来换行。因此,对于以下字节序列:

第一行:"test1"
第二行:"123;\n234;\n345;"
第三行:"456;\n567;"
第四行:"test4"

在处理整个序列时,我希望得到3行,而不是总共得到7行。这是一个旧项目,但我记得我可以使用Python直接使用类似"for line in f"的语法获取3行,并打印第二个内部字符串的内容而不是渲染它。

英文:

I am trying read certain string output generated by linux command by the following code:

out, err := exec.Command("sh", "-c", cmd).Output()

The above out is of []byte type, how can I differentiate the "\n" character contained in line content with the real line break? I tried

strings.Split(output, "\n")

and

bufio.NewScanner(strings.NewReader(output))

but they both split the whole string buffer whenever seeing a "\n" character.

OK, to clarify, an "unreal" break is a "\n" character contained in a string as follows,

Print first result: "123;\n234;\n"
Print second result: "456;\n"

The whole output is one big multi-line string, it may also contain some other quoted strings, and I am processing the whole string output in my go program, but I can't control the command output and add a back slash before the "\n" character.

Further clarify: I meant to process byte sequence which contains string of strings, and want to preserve the "\n" contained in the inner string and use the the outer layer "\n" to break lines. So for the following byte sequence:

First line: "test1"
Second line: "123;\n234;\n345;"
Third line: "456;\n567;"
Fourth line: "test4"

I want to get 3 lines when processing the whole sequence, instead of getting 7 total lines. It's a old project, but I remember I can use Python to directly get 3 lines using syntax like "for line in f", and print the content of second inner string instead of rendering it.

答案1

得分: 31

可能你的 "\n" 实际上是转义后的换行符版本。你可以通过搜索转义版本并替换为非转义版本来将其替换为真正的换行符:

strings.Replace(sourceStr, `\n`, "\n", -1)

由于反引号内的字符串文字可以跨多行编写,Go 会转义它遇到的任何换行符字符。

英文:

It's possible that your "\n" is actually the escaped version of a line break character. You can replace these with real line breaks by searching for the escaped version and replacing with the non escaped version:

strings.Replace(sourceStr, `\n`, "\n", -1)

Since string literals inside backticks can be written over multiple lines, Go escapes any line break characters it sees.

答案2

得分: 28

在一个文本文件中,无论是“真实”的还是“虚构”的换行符都没有区别。

如果你使用类Unix系统,文本文件中的行尾由LF或'\n'字符表示。你不能在一行的中间插入'\n'字符。

内存中的字符串可以包含任意多个'\n'字符。当将字符串"foo\nbar\n"写入文本文件时,将创建两行,即"foo""bar"

以下代码片段是等效的:

fmt.Println("foo")
fmt.Println("bar")

fmt.Printf("foo\nbar\n")

两者都打印出相同的2行序列,与下面的代码也是一样的:

fmt.Println("foo\nbar")
英文:

There is no distinction between a "real" and an "unreal" line break.

If you're using a Unix-like system, the end of a line in a text file is denoted by the LF or '\n' character. You cannot have a '\n' character in the middle of a line.

A string in memory can contain as many '\n' characters as you like. The string "foo\nbar\n", when written to a text file, will create two lines, "foo" and "bar".

There is no effective difference between

fmt.Println("foo")
fmt.Println("bar")

and

fmt.Printf("foo\nbar\n")

Both print the same sequence of 2 lines, as does this:

fmt.Println("foo\nbar")

答案3

得分: 2

encoding/csv包可能适合您的需求:

package main

import (
   "encoding/csv"
   "fmt"
   "strings"
)

const s = `First line: "test1"
Second line: "123;
234;
345;"
Third line: "456;
567;"
Fourth line: "test4"
`

func main() {
   r := csv.NewReader(strings.NewReader(s))
   r.Comma = ':'
   r.TrimLeadingSpace = true
   a, e := r.ReadAll()
   if e != nil {
      panic(e)
   }
   fmt.Printf("%q\n", a)
}

结果:

[
   ["First line" "test1"]
   ["Second line" "123;\n234;\n345;"]
   ["Third line" "456;\n567;"]
   ["Fourth line" "test4"]
]

https://golang.org/pkg/encoding/csv

英文:

The encoding/csv package might suit your needs:

package main

import (
   "encoding/csv"
   "fmt"
   "strings"
)

const s = `First line: "test1"
Second line: "123;
234;
345;"
Third line: "456;
567;"
Fourth line: "test4"
`

func main() {
   r := csv.NewReader(strings.NewReader(s))
   r.Comma = ':'
   r.TrimLeadingSpace = true
   a, e := r.ReadAll()
   if e != nil {
      panic(e)
   }
   fmt.Printf("%q\n", a)
}

Result:

[
   ["First line" "test1"]
   ["Second line" "123;\n234;\n345;"]
   ["Third line" "456;\n567;"]
   ["Fourth line" "test4"]
]

https://golang.org/pkg/encoding/csv

答案4

得分: 0

strings.Trim(string, "\f\t\r\n ")的中文翻译是:去除字符串两端的空格、制表符、回车符和换行符。

英文:
strings.Trim(string, "\f\t\r\n ")

huangapple
  • 本文由 发表于 2015年8月17日 12:50:16
  • 转载请务必保留本文链接:https://go.coder-hub.com/32042989.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定