Golang 替换所有换行符

通常,当我替换换行符时,我会跳转到正则表达式,就像在这个 PHP 中一样

preg_replace('/\R/u', "\n", $String);

因为我知道这是替换任何类型的 Unicode 换行符(无论是 \n、\r、\r\n 等)的一种非常持久的方法

我也在尝试在 Go 中做这样的事情,但我得到了

解析正则表达式时出错:转义序列无效:\R

在这条线上

msg = regexp.MustCompilePOSIX("\\R").ReplaceAllString(html.EscapeString(msg), "<br>\n")

我尝试使用(?:(?>\r\n)|\v)https://stackoverflow.com/a/4389171/728236 但看起来 Go 的正则表达式实现也不支持它,恐慌invalid or unsupported Perl syntax: '(?>'

什么是替换 Go 中的换行符的好、安全的方法,Regex 与否?


我在这里看到这个答案Golang:Issues replacing newlines in a string from a text file saying to use \r?\n,但我犹豫是否相信它会得到所有Unicode 换行符,主要是因为这个问题的答案列出了比覆盖的3个\r?\n


阿波罗的战车
浏览 325回答 2
2回答

大话西游666

虽然使用 regexp 通常会产生一个优雅而紧凑的解决方案,但它通常不是最快的。对于必须用其他子字符串替换某些子字符串的任务,标准库以以下形式提供了一个非常有效的解决方案strings.Replacer:Replacer 用替换项替换字符串列表。多个 goroutines 并发使用是安全的。您可以使用创建可重复使用的替换器strings.NewReplacer(),其中列出包含可替换部件及其替换件的对。当你想执行替换时,你只需调用Replacer.Replace().它看起来像这样:const replacement = "<br>\n"var replacer = strings.NewReplacer(    "\r\n", replacement,    "\r", replacement,    "\n", replacement,    "\v", replacement,    "\f", replacement,    "\u0085", replacement,    "\u2028", replacement,    "\u2029", replacement,)func replaceReplacer(s string) string {    return replacer.Replace(s)}以下是Wiktor 答案中的正则表达式解决方案:var re = regexp.MustCompile(`\r\n|[\r\n\v\f\x{0085}\x{2028}\x{2029}]`)func replaceRegexp(s string) string {    return re.ReplaceAllString(s, "<br>\n")}实施实际上相当快。这是一个简单的基准测试,将其与上述预编译的正则表达式解决方案进行比较:const input = "1st\nsecond\r\nthird\r4th\u0085fifth\u2028sixth"func BenchmarkReplacer(b *testing.B) {    for i := 0; i < b.N; i++ {        replaceReplacer(input)    }}func BenchmarkRegexp(b *testing.B) {    for i := 0; i < b.N; i++ {        replaceRegexp(input)    }}基准测试结果:BenchmarkReplacer-4      3000000               495 ns/opBenchmarkRegexp-4         500000              2787 ns/op对于我们的测试输入,速度提高了5 倍strings.Replacer以上。还有另一个优点。在上面的示例中,我们将结果作为新string值获取(在两种解决方案中)。这需要一个新的string分配。如果我们需要将结果写入一个io.Writer(例如,我们正在创建一个 HTTP 响应或将结果写入一个文件),我们可以避免必须创建新的,string因为strings.Replacer它有一个方便的Replacer.WriteString()方法,它接受一个io.Writer并写入result into 它而不分配并将其作为 a 返回string。与正则表达式解决方案相比,这进一步显着提高了性能增益。

心有法竹

您可以将模式“解码”\R为U+000DU+000A|[U+000AU+000BU+000CU+000DU+0085U+2028U+2029]请参阅解释速记的Java 正则表达式文档\R:Linebreak matcher\R&nbsp; Any Unicode linebreak sequence, is equivalent to \u000D\u000A|[\u000A\u000B\u000C\u000D\u0085\u2028\u2029]在 Go 中,您可以使用以下内容:func removeLBR(text string) string {&nbsp; &nbsp; re := regexp.MustCompile(`\x{000D}\x{000A}|[\x{000A}\x{000B}\x{000C}\x{000D}\x{0085}\x{2028}\x{2029}]`)&nbsp; &nbsp; return re.ReplaceAllString(text, ``)}这是一个Go 演示。一些 Unicode 代码可以用Go regexp支持的正则表达式转义序列替换:re := regexp.MustCompile(`\r\n|[\r\n\v\f\x{0085}\x{2028}\x{2029}]`)
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go