将带角括号的嵌入式UTF8十六进制值转换为重音字符

2024-04-25 09:00:32 发布

您现在位置:Python中文网/ 问答频道 /正文

在pandasread_json中,UTF-8重音或数字字符被转换为相应十六进制值的尖括号。如何避免或修复此问题以呈现实际的UTF-8字符值

考虑下面的示例,该示例从所有当前R GITHUB CRAN包的S3桶中提取。请注意,重音字符的输出由带角括号的十六进制值表示:

import pandas as pd

# S3 (REQUIRES s3fs)
json_df = pd.read_json("s3://public-r-data/ghcran.json")

# URL (NO REQUIREMENT)
json_df = pd.read_json("http://public-r-data.s3-website-us-east-1.amazonaws.com/ghcran.json")

json_df.loc[884, "Title"]
# Misc Functions of Eduard Sz<c3><b6>cs

json_df.loc[213, "Author"]
# Kirill M<c3><bc>ller [aut, cre]

json_df.loc[336, "Maintainer"]
# H<c3><a9>l<c3><a8>ne Morlon <morlon@biologie.ens.fr>

为了避免为这些十六进制值使用映射字典替换解决方案,是否有一个紧凑的解决方案来避免或将这些嵌入的十六进制值修复为实际的UTF-8字符?具体而言,如何将上述结果转换为以下结果:

# Misc Functions of Eduard Szöcs

# Kirill Müller [aut, cre]

# Hélène Morlon <morlon@biologie.ens.fr>

Tags: json示例dfreaddatas3public字符
1条回答
网友
1楼 · 发布于 2024-04-25 09:00:32

啊。。。错误编码字符串的痛苦!我曾经遇到过类似的问题,下面是我如何解决它的改编版本

它将原始字符串分解为一个字节数组,然后将一些字节组合在一起,并将新数组重新编码为UTF-8。这远不是万无一失的,但可能不是问题,这取决于您的要求:

def reencode(string):
    def is_hex(i):
        return (48 <= i <= 57) or (97 <= i <= 102)
    
    def to_bytes(arr):
        if len(arr) != 4:
            return None
        
        a, b, c, d = arr
        if a == 60 and is_hex(b) and is_hex(c) and d == 62:
            return bytes.fromhex(chr(b) + chr(c))

        return None

    old = string.encode('ascii')
    new = bytearray()

    i = 0
    while i < len(old):
        b = to_bytes(old[i:i+4])
        if b:
            new.extend(b)
            i += 4
        else:
            new.append(old[i])
            i += 1
    return new.decode('utf8')

测试:

df = pd.DataFrame([
    'Misc Functions of Eduard Sz<c3><b6>cs',
    'Kirill M<c3><bc>ller [aut, cre]',
    'H<c3><a9>l<c3><a8>ne Morlon <morlon@biologie.ens.fr>'
], columns=['name'])
df['name'].apply(reencode)

输出:

0            Misc Functions of Eduard Szöcs
1                  Kirill Müller [aut, cre]
2    Hélène Morlon <morlon@biologie.ens.fr>

相关问题 更多 >

    热门问题