gpt4 book ai didi

string - 清理错误的 UTF-8 字符串

转载 作者:行者123 更新时间:2023-12-02 23:35:56 26 4
gpt4 key购买 nike

由于用户数据格式错误,我的 gRPC 服务无法发送请求。结果 HR 用户数据有一个错误的 UTF-8 字符串,并且 gRPC 无法对其进行编码。我将错误字段缩小到这个字符串:

"Gr\351gory Smith" // Gr�gory Smith  (this is coming from an LDAP source)

因此,如果这些输入包含错误的 UTF-8 编码,我想要一种方法来对其进行清理。

unicode/utf8 标准包中没有看到任何明显的清理功能,这是我的第一次天真的尝试:

func naïveSanitizer(in string) (out string) {
for _, rune := range in {
out += string(rune)
}
return
}

输出:

Before: Valid UTF-8? false  Name: 'Gr�gory Smith' Byte-Count:  13
After: Valid UTF-8? true Name: 'Gr�gory Smith' Byte-Count: 15

Playground version

是否有更好或更标准的方法来从错误的 UTF-8 字符串中挽救尽可能多的有效数据?

<小时/>

我在这里暂停的原因是因为在迭代字符串并遇到错误(第三个)字符时,utf8.ValidRune(rune) 返回true:https://play.golang.org/p/_FZzeTRLVls

所以我的后续问题是,迭代一个字符串(一次一个 rune ) rune 值是否始终有效?即使底层源字符串编码格式错误?

<小时/>

编辑:

澄清一下,此数据来自 LDAP 源:500K 用户记录。在这 500K 条记录中,只有 15(十五)条,即约 0.03% 返回 uf8.ValidString(...)false

正如 @kostix 和 @peterSO 所指出的,如果从另一种编码(例如 Latin-1)转换为 UTF-8,这些值可能是有效的。将此理论应用于这些异常样本:

https://play.golang.org/p/9BA7W7qQcV3

Name:     "Jean-Fran\u00e7ois Smith" : (good UTF-8) :            : Jean-François Smith
Name: "Gr\xe9gory" : (bad UTF-8) : Latin-1-Fix: Grégory
Name: "Fr\xe9d\xe9ric" : (bad UTF-8) : Latin-1-Fix: Frédéric
Name: "Fern\xe1ndez" : (bad UTF-8) : Latin-1-Fix: Fernández
Name: "Gra\xf1a" : (bad UTF-8) : Latin-1-Fix: Graña
Name: "Mu\xf1oz" : (bad UTF-8) : Latin-1-Fix: Muñoz
Name: "P\xe9rez" : (bad UTF-8) : Latin-1-Fix: Pérez
Name: "Garc\xeda" : (bad UTF-8) : Latin-1-Fix: García
Name: "Gro\xdfmann" : (bad UTF-8) : Latin-1-Fix: Großmann
Name: "Ure\xf1a" : (bad UTF-8) : Latin-1-Fix: Ureña
Name: "Iba\xf1ez" : (bad UTF-8) : Latin-1-Fix: Ibañez
Name: "Nu\xf1ez" : (bad UTF-8) : Latin-1-Fix: Nuñez
Name: "Ba\xd1on" : (bad UTF-8) : Latin-1-Fix: BaÑon
Name: "Gonz\xe1lez" : (bad UTF-8) : Latin-1-Fix: González
Name: "Garc\xeda" : (bad UTF-8) : Latin-1-Fix: García
Name: "Guti\xe9rrez" : (bad UTF-8) : Latin-1-Fix: Gutiérrez
Name: "D\xedaz" : (bad UTF-8) : Latin-1-Fix: Díaz
Name: "Encarnaci\xf3n" : (bad UTF-8) : Latin-1-Fix: Encarnación

最佳答案

你可以通过删除无效的 rune 来改进你的“ sanitizer ”:

package main

import (
"fmt"
"strings"
)

func notSoNaïveSanitizer(s string) string {
var b strings.Builder
for _, c := range s {
if c == '\uFFFD' {
continue
}
b.WriteRune(c)
}
return b.String()
}

func main() {
fmt.Println(notSoNaïveSanitizer("Gr\351gory Smith"))
}

Playground .

问题是 \351Latin-1 中的字符 é .

@PeterSO 指出它也恰好位于 Unicode 的 BMP 中的相同位置,这是正确的,但 Unicode 不是一种编码,并且您的数据应该被编码,所以我认为您只是对数据的编码,它不是 UTF-8,而是 Latin-1(或与拉丁重音字母兼容的编码)。

所以我会验证你确实正在处理 Latin-1 (或其他),如果是这样, golang.org/x/text/encoding提供完整的工具,用于从旧编码重新编码为 UTF-8(或其他编码)。

(顺便说一句,您也可能不明确要求数据源为您提供 UTF-8 编码的数据。)

关于string - 清理错误的 UTF-8 字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58017462/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com