摆脱 unicode 十进制字符
Get rid of unicode decimal charater
我有一个很大的文件,如下所示:
6814;gymnocéphale;185;151;49
6815;gymnodonte;83;330;0
6816;gymnosome;287;105;42
6817;hà mã;69;305;0
6818;hải âu;81;294;0
6819;hải cẩu;64;338;0
6820;hải yến;62;269;0
6848;histiophore;57;262;0
6849;hiverneur;56;248;0
6850;hổmang;54;298;0
6851;holobranche;97;329;0
6852;hoplopode;65;296;0
6853;hươu cao cổ152;298;0
6854;huyền đề62;324;0
6855;hyalosome;73;371;0
6883;jumarre;83;295;0
6884;kéc;86;326;0
6885;kền kền;73;303;0
6886;khoang;64;323;0
6887;khướu;62;325;0
如您所见,该文件包含一些 unicode 十进制,我想在使用该文件之前将它们全部替换为拉丁字符。即使用utf-8编码打开,也没有抑制错误。
你知道怎么做吗?我想创建一个字典并检索索引 2 处的数字。
for : 6883;jumarre;83;295;0; => i have 83
for : 6887;khướu;62;325;0 => i have ớ => which is false , i should have 62
with codecs.open('JeuxdeMotsPolarise_test.txt', 'r', 'utf-8', errors = 'ignore') as text_file:
text_file =(text_file.read())
#print(text_file)
dico_lexique = ({i.split(";")[1]:i.split(";")[2:]for i in text_file.split("\n") if i})
这是尝试@serge 命题给出的结果,但行与行之间留有空格。
6814;gymnocéphale;185;151;49
6815;gymnodonte;83;330;0
6816;gymnosome;287;105;42
6817;hà mã;69;305;0
6818;hi âu;81;294;0
6819;hi cu;64;338;0
6820;hi yn;62;269;0
6848;histiophore;57;262;0
6849;hiverneur;56;248;0
6850;h mang;54;298;0
6851;holobranche;97;329;0
6852;hoplopode;65;296;0
6853;hu cao c;152;298;0
6854;huyn ;62;324;0
6855;hyalosome;73;371;0
6883;jumarre;83;295;0
6884;kéc;86;326;0
6885;kn kn;73;303;0
6886;khoang;64;323;0
6887;khu;62;325;0
编辑:我重新下载原文件,报错“;”已更正。
例如:
=> 6850;hổ mang;54;298;0(这就是现在更新文件中出现的方式)
谢谢大家
先修复文件,然后再将其加载到 CSV 解析器中。
假设评论中的 Maarten 是正确的,更改编码:
iconv -f cp1252 -t utf-8 < JeuxdeMotsPolarise_test.txt > JeuxdeMotsPolarise_test.utf8.txt
然后用适当的字符替换转义符。
perl -C -i -lpe'
s/&#([0-9]+);?/chr /eg; # replace entities
s/;?(\d+;\d+;\d+)$/;/; # put back semicolon
# if it was consumed accidentally
' JeuxdeMotsPolarise_test.utf8.txt
运行 替换后 JeuxdeMotsPolarise_test.utf8.txt
的内容:
6814;gymnocéphale;185;151;49
6815;gymnodonte;83;330;0
6816;gymnosome;287;105;42
6817;hà mã;69;305;0
6818;hải âu;81;294;0
6819;hải cẩu;64;338;0
6820;hải yến;62;269;0
6848;histiophore;57;262;0
6849;hiverneur;56;248;0
6850;hổmang;54;298;0
6851;holobranche;97;329;0
6852;hoplopode;65;296;0
6853;hươu cao cổ;152;298;0
6854;huyền đề;62;324;0
6855;hyalosome;73;371;0
6883;jumarre;83;295;0
6884;kéc;86;326;0
6885;kền kền;73;303;0
6886;khoang;64;323;0
6887;khướu;62;325;0
此文本通常不是 UTF8 或 Unicode。是 HTML-encoded text,很可能是越南人。那些转义序列对应于越南字符,例如 ư
是 ư - 事实上,我只是在 SO 编辑框中键入编辑序列,然后出现了正确的字符。 ớ
是 ớ.
复制代码块外的整个文本会产生
6814;gymnocéphale;185;151;49
6815;gymnodonte;83;330;0
6816;裸子体;287;105;42
6817;hà mã;69;305;0
6818;hải âu;81;294;0
6819;hải cẩu;64;338;0
6820;hải yến;62;269;0
6848;组织细胞;57;262;0
6849;hiverneur;56;248;0
6850;hổmang;54;298;0
6851;全分支;97;329;0
6852;hoplopode;65;296;0
6853;hươu cao cổ152;298;0
6854;huyền đề62;324;0
6855;透明体;73;371;0
6883;jumarre;83;295;0
6884;kéc;86;326;0
6885;kền kền;73;303;0
6886;khoang;64;323;0
6887;khướu;62;325;0
谷歌搜索 Họ Khướu returns this Wikipedia page about Họ Khướu.
我认为可以安全地假设这是 HTML-encoded 越南语文本。要将其转换为 Unicode,您可以使用 html.unescape :
import html
line='6887;khướu;62;325;0'
properLine=html.unescape(line)
更新
上面发布的文字只是原文,每页多了一个换行符。 SO 的降价渲染器将转义序列转换为相应的字形。
有趣的是这一行:
6853;hươu cao cổ152;298;0
无法呈现,因为 HTML 实体未正确终止。 html.unescape
另一方面 将 转换字符。显然,html.unescape
比 SO 的降价渲染器更宽容。
以下任一行:
html.unescape('6853;hươu cao cổ152;298;0')
html.unescape('6853;hươu cao cổ152;298;0')
Returns :
6853;h\u01b0\u01a1u cao c\u1ed5152;298;0
@PanagiotisKanavos 正确地猜测 html.unescape
能够用他们的 unicode 字符替换 xml 字符引用。困难的部分是一些 refs 以它们的终止分号 (;
) 正确结束,而另一些则不是。在后一种情况下,如果一个实体后跟分号 分隔符 ,则分隔符将被转换吃掉,从而移动以下字段。
所以唯一可靠的方法是:
- 像使用
;
定界符 一样逐行处理文件作为 CSV 文件
- 最终将中间字段从第二个开始连接到第四个开始
- 取消中间字段
如果你想转换文件,你可以这样做:
with open('file.csv') as fd, open('fixed.csv', 'w', newline='') as fdout:
rd = csv.reader(fd, delimiter=';')
wr = csv.writer(fdout, delimiter=';')
for row in rd:
if len(row)> 5:
row[1] = ';'.join(row[1:len(row)-3])
del row[2:len(row)-3]
row[1] = html.unescape(row[1])
wr.writerow(row)
如果您只想构建从字段 0 到字段 2 的映射:
values = {}
with open('file.csv') as fd:
rd = csv.reader(fd, delimiter=';')
for row in rd:
values[field[0]] = field[-3]
我有一个很大的文件,如下所示:
6814;gymnocéphale;185;151;49
6815;gymnodonte;83;330;0
6816;gymnosome;287;105;42
6817;hà mã;69;305;0
6818;hải âu;81;294;0
6819;hải cẩu;64;338;0
6820;hải yến;62;269;0
6848;histiophore;57;262;0
6849;hiverneur;56;248;0
6850;hổmang;54;298;0
6851;holobranche;97;329;0
6852;hoplopode;65;296;0
6853;hươu cao cổ152;298;0
6854;huyền đề62;324;0
6855;hyalosome;73;371;0
6883;jumarre;83;295;0
6884;kéc;86;326;0
6885;kền kền;73;303;0
6886;khoang;64;323;0
6887;khướu;62;325;0
如您所见,该文件包含一些 unicode 十进制,我想在使用该文件之前将它们全部替换为拉丁字符。即使用utf-8编码打开,也没有抑制错误。
你知道怎么做吗?我想创建一个字典并检索索引 2 处的数字。
for : 6883;jumarre;83;295;0; => i have 83
for : 6887;khướu;62;325;0 => i have ớ => which is false , i should have 62
with codecs.open('JeuxdeMotsPolarise_test.txt', 'r', 'utf-8', errors = 'ignore') as text_file:
text_file =(text_file.read())
#print(text_file)
dico_lexique = ({i.split(";")[1]:i.split(";")[2:]for i in text_file.split("\n") if i})
这是尝试@serge 命题给出的结果,但行与行之间留有空格。
6814;gymnocéphale;185;151;49
6815;gymnodonte;83;330;0
6816;gymnosome;287;105;42
6817;hà mã;69;305;0
6818;hi âu;81;294;0
6819;hi cu;64;338;0
6820;hi yn;62;269;0
6848;histiophore;57;262;0
6849;hiverneur;56;248;0
6850;h mang;54;298;0
6851;holobranche;97;329;0
6852;hoplopode;65;296;0
6853;hu cao c;152;298;0
6854;huyn ;62;324;0
6855;hyalosome;73;371;0
6883;jumarre;83;295;0
6884;kéc;86;326;0
6885;kn kn;73;303;0
6886;khoang;64;323;0
6887;khu;62;325;0
编辑:我重新下载原文件,报错“;”已更正。
例如:
=> 6850;hổ mang;54;298;0(这就是现在更新文件中出现的方式)
谢谢大家
先修复文件,然后再将其加载到 CSV 解析器中。
假设评论中的 Maarten 是正确的,更改编码:
iconv -f cp1252 -t utf-8 < JeuxdeMotsPolarise_test.txt > JeuxdeMotsPolarise_test.utf8.txt
然后用适当的字符替换转义符。
perl -C -i -lpe'
s/&#([0-9]+);?/chr /eg; # replace entities
s/;?(\d+;\d+;\d+)$/;/; # put back semicolon
# if it was consumed accidentally
' JeuxdeMotsPolarise_test.utf8.txt
运行 替换后 JeuxdeMotsPolarise_test.utf8.txt
的内容:
6814;gymnocéphale;185;151;49
6815;gymnodonte;83;330;0
6816;gymnosome;287;105;42
6817;hà mã;69;305;0
6818;hải âu;81;294;0
6819;hải cẩu;64;338;0
6820;hải yến;62;269;0
6848;histiophore;57;262;0
6849;hiverneur;56;248;0
6850;hổmang;54;298;0
6851;holobranche;97;329;0
6852;hoplopode;65;296;0
6853;hươu cao cổ;152;298;0
6854;huyền đề;62;324;0
6855;hyalosome;73;371;0
6883;jumarre;83;295;0
6884;kéc;86;326;0
6885;kền kền;73;303;0
6886;khoang;64;323;0
6887;khướu;62;325;0
此文本通常不是 UTF8 或 Unicode。是 HTML-encoded text,很可能是越南人。那些转义序列对应于越南字符,例如 ư
是 ư - 事实上,我只是在 SO 编辑框中键入编辑序列,然后出现了正确的字符。 ớ
是 ớ.
复制代码块外的整个文本会产生
6814;gymnocéphale;185;151;49
6815;gymnodonte;83;330;0
6816;裸子体;287;105;42
6817;hà mã;69;305;0
6818;hải âu;81;294;0
6819;hải cẩu;64;338;0
6820;hải yến;62;269;0
6848;组织细胞;57;262;0
6849;hiverneur;56;248;0
6850;hổmang;54;298;0
6851;全分支;97;329;0
6852;hoplopode;65;296;0
6853;hươu cao cổ152;298;0
6854;huyền đề62;324;0
6855;透明体;73;371;0
6883;jumarre;83;295;0
6884;kéc;86;326;0
6885;kền kền;73;303;0
6886;khoang;64;323;0
6887;khướu;62;325;0
谷歌搜索 Họ Khướu returns this Wikipedia page about Họ Khướu.
我认为可以安全地假设这是 HTML-encoded 越南语文本。要将其转换为 Unicode,您可以使用 html.unescape :
import html
line='6887;khướu;62;325;0'
properLine=html.unescape(line)
更新
上面发布的文字只是原文,每页多了一个换行符。 SO 的降价渲染器将转义序列转换为相应的字形。
有趣的是这一行:
6853;hươu cao cổ152;298;0
无法呈现,因为 HTML 实体未正确终止。 html.unescape
另一方面 将 转换字符。显然,html.unescape
比 SO 的降价渲染器更宽容。
以下任一行:
html.unescape('6853;hươu cao cổ152;298;0')
html.unescape('6853;hươu cao cổ152;298;0')
Returns :
6853;h\u01b0\u01a1u cao c\u1ed5152;298;0
@PanagiotisKanavos 正确地猜测 html.unescape
能够用他们的 unicode 字符替换 xml 字符引用。困难的部分是一些 refs 以它们的终止分号 (;
) 正确结束,而另一些则不是。在后一种情况下,如果一个实体后跟分号 分隔符 ,则分隔符将被转换吃掉,从而移动以下字段。
所以唯一可靠的方法是:
- 像使用
;
定界符 一样逐行处理文件作为 CSV 文件
- 最终将中间字段从第二个开始连接到第四个开始
- 取消中间字段
如果你想转换文件,你可以这样做:
with open('file.csv') as fd, open('fixed.csv', 'w', newline='') as fdout:
rd = csv.reader(fd, delimiter=';')
wr = csv.writer(fdout, delimiter=';')
for row in rd:
if len(row)> 5:
row[1] = ';'.join(row[1:len(row)-3])
del row[2:len(row)-3]
row[1] = html.unescape(row[1])
wr.writerow(row)
如果您只想构建从字段 0 到字段 2 的映射:
values = {}
with open('file.csv') as fd:
rd = csv.reader(fd, delimiter=';')
for row in rd:
values[field[0]] = field[-3]