gpt4 book ai didi

python - 在Python3中将unicode序列转换为字符串但允许字符串中的路径

转载 作者:行者123 更新时间:2023-12-01 01:35:38 25 4
gpt4 key购买 nike

至少有one related question on SO这在尝试解码 unicode 序列时被证明是有用的。

我正在预处理许多不同类型的文本。有些是经济性的,有些是技术性的,等等。注意事项之一是转换 unicode 序列:

'Korado's output has gone up from 180,000 radiators per year to almost 1.7 million today,' says Vojt\u0115ch \u010camek.

这样的字符串需要转换为实际的字符:

'Korado's output has gone up from 180,000 radiators per year to almost 1.7 million today,' says Vojtĕch Čamek.

可以这样完成:

s = "'Korado's output has gone up from 180,000 radiators per year to almost 1.7 million today,' says Vojt\u0115ch \u010camek."
s = s.encode('utf-8').decode('unicode-escape')

(至少当 s 是从 utf-8 编码的文本文件中获取的输入行时,这是有效的。我似乎无法让它在像 REPL.it 这样的在线服务,输出的编码/解码方式不同。)

在大多数情况下,这都可以正常工作。但是,当在输入字符串中看到目录结构路径时(通常是我的数据集中的技术文档的情况),则会发生 UnicodeDecodeError

给定以下数据unicode.txt:

'Korado's output has gone up from 180,000 radiators per year to almost 1.7 million today,' says Vojt\u0115ch \u010camek, Financial Director and Director of Controlling.
Voor alle bestanden kan de naam met de volledige padnaam (bijvoorbeeld: /u/slick/udfs/math.a (op UNIX), d:\udfs\math.dll (op Windows)).

用字节串表示:

b"'Korado's output has gone up from 180,000 radiators per year to almost 1.7 million today,' says Vojt\\u0115ch \\u010camek, Financial Director and Director of Controlling.\r\nVoor alle bestanden kan de naam met de volledige padnaam (bijvoorbeeld: /u/slick/udfs/math.a (op UNIX), d:\\udfs\\math.dll (op Windows))."

解码输入文件中的第二行时,以下脚本将失败:

with open('unicode.txt', 'r', encoding='utf-8') as fin, open('unicode-out.txt', 'w', encoding='utf-8') as fout:
lines = ''.join(fin.readlines())
lines = lines.encode('utf-8').decode('unicode-escape')

fout.write(lines)

有痕迹:

Traceback (most recent call last):
File "C:/Python/files/fast_aligning/unicode-encoding.py", line 3, in <module>
lines = lines.encode('utf-8').decode('unicode-escape')
UnicodeDecodeError: 'unicodeescape' codec can't decode bytes in position 275-278: truncated \uXXXX escape

Process finished with exit code 1

如何确保第一个句子仍然正确“翻译”(如前所示),但第二个句子保持不变?因此,给定的两行的预期输出如下,其中第一行已更改,第二行未更改。

'Korado's output has gone up from 180,000 radiators per year to almost 1.7 million today,' says Vojtĕch Čamek.
Voor alle bestanden kan de naam met de volledige padnaam (bijvoorbeeld: /u/slick/udfs/math.a (op UNIX), d:\udfs\math.dll (op Windows)).

最佳答案

输入的内容不明确。一般情况下不存在正确答案。我们可以使用启发式方法来生成大多数情况下看起来正确的输出,例如,我们可以使用诸如“if \uxxxx 序列(6 个字符)是现有路径的一部分”之类的规则那么不要将其解释为 Unicode 转义”,对于 \Uxxxxxxxx(10 个字符)序列也是如此,例如,与问题中的输入类似的输入: b"c:\\U0001f60f\\math.dll" 可以有不同的解释,具体取决于 c:\U0001f60f\math.dll 文件是否实际存在于磁盘上:

#!/usr/bin/env python3
import re
from pathlib import Path


def decode_unicode_escape_if_path_doesnt_exist(m):
path = m.group(0)
return path if Path(path).exists() else replace_unicode_escapes(path)


def replace_unicode_escapes(text):
return re.sub(
fr"{unicode_escape}+",
lambda m: m.group(0).encode("latin-1").decode("raw-unicode-escape"),
text,
)


input_text = Path('broken.txt').read_text(encoding='ascii')
hex = "[0-9a-fA-F]"
unicode_escape = fr"(?:\\u{hex}{{4}}|\\U{hex}{{8}})"
drive_letter = "[a-zA-Z]"
print(
re.sub(
fr"{drive_letter}:\S*{unicode_escape}\S*",
decode_unicode_escape_if_path_doesnt_exist,
input_text,
)
)

如果编码文本中存在非 ASCII 字符,请在 read_text() 中指定 broken.txt 文件的实际编码。

用于提取路径的特定正则表达式取决于您获得的输入类型。

您可以通过尝试一次替换一个可能的 Unicode 序列来使代码复杂化(在这种情况下,替换的数量随着候选者的数量呈指数增长,例如,如果路径中有 10 个可能的 Unicode 转义序列,则有2**10 解码路径来尝试)。

关于python - 在Python3中将unicode序列转换为字符串但允许字符串中的路径,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52425315/

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