在NodeJS中将windows1252编码转换为utf-8,处理特殊字符。

3
我正在使用NodeJS版本12构建Web应用程序。我有来自旧的MySQL数据库的数据。由于旧数据库的编码问题,有几个字段包含无法正确显示的字符。已经有一些类似的问题,但没有一个解决了我的问题。经过尝试,我离找到解决方案更近了一步,但仍需要帮助。
要转换的数据库当前值:
Rikuchi SokuryoÌ„bu [cartographer], 陸地測é‡éƒ¨

期望的新数据库值:
Rikuchi Sokuryōbu [cartographer], 陸地測量部

问题与这个类似问题描述的相同。但是,被接受的答案没有解决我的问题。我需要编写一个NodeJS程序将数据库中的数据转换为可读字符串。

我也尝试了这个类似问题的答案。我明白值需要先转换为二进制,然后再转换为所需的编码。然而,它没有返回期望的结果。我试过使用iconv和iconv-lite包。

尝试1:

let buf = new Buffer(body, 'binary');
let conv = new iconv.Iconv('windows-1252', 'utf8');
let str = conv.convert(buf).toString();
console.log(`original: ${body} output: ${str.toString()}`);

// original: Rikuchi SokuryoÌ„bu [cartographer], 陸地測é‡éƒ¨
// output: Rikuchi SokuryoМbu [cartographer], й"ёеS°жё¬й!Џй’Ё

尝试2:iconv-lite
let buf = new Buffer(body, 'binary');
const str = iconvlite.decode(buf, 'windows-1252');
console.log(`original: ${body} output: ${str.toString()}`);

// original: Rikuchi SokuryoÌ„bu [cartographer], 陸地測é‡éƒ¨
// output: Rikuchi SokuryoМbu [cartographer], й"ёеS°жё¬й!Џй’Ё

尝试3:iconv-lite
// This one *almost* works however there are still some undefined characters

let buf = new Buffer(body, 'utf-8');
const win = iconvlite.encode(buf, 'windows-1252');
console.log(`original: ${body} output: ${win.toString()}`);

// original: Rikuchi SokuryoÌ„bu [cartographer], 陸地測é‡éƒ¨
// output: Rikuchi Sokuryōbu [cartographer], 陸地測�?部

更新:

这个网站 string-functions.com 可以对字符串进行编码和解码。

在设置为“使用 Windows-1252 编码”和“使用 utf-8 解码”的情况下,整个有问题的字符串都可以正确解码。

它也可以完美地处理更大的类似问题的示例。我只需要复制这个网站如何进行转换的步骤。我的第三次尝试非常接近,但可能缺少一步。

stringfunctions.com

3个回答

5

非常好的文章,感谢@pengz,这对我很有帮助。我同意其他解决方案都忽略了撇号和其他字符。这是唯一适用于我的解决方案。不过需要注意一点:我能够使用iconvlite完成相同的操作:

const win = iconvlite.encode(body, 'windows-1252');
const str = iconvlite.decode(win, 'utf-8');
return str.toString();

对于未来任何想要使用这段代码的人,我尝试过使用Iconv进行从编码到windows-1252和解码到utf-8的转换,但对于我来说仅在某些情况下有效。使用windows-1252模块似乎更可靠用于编码到windows-1252。请确保尝试两种方法以确定哪种适合您的情况。 - Jaxon Crosmas

4

我使用windows-1252模块对原始文本进行编码,然后使用iconv-lite模块对其进行解码以解决此问题。

const win = windows1252.encode(body);
const str = iconvlite.decode(win, 'utf-8');
return str.toString();

1
我称这个方案为“Base256”:将字节字符串视为文本进行解码,使用支持任意0-255字节值序列的字符编码进行编码。具体的字符编码应该有文档记录。在这种情况下,字节序列是将UTF-8字符编码应用于文本的结果。这也应该被记录。你已经发现了如何反转这两个步骤。 - Tom Blodget
1
我曾经遇到过一些旧的latin1 mysql表格的相同问题,而这是唯一一个能够正确获取所有字符的解决方案!Windows-1252模块可以正确编码Don't worry.Malört,而其他所有解决方案都会错过撇号或ö。 - broox
1
这是一篇旧帖子,但它可能刚刚让我免去了人生中最大的头痛。 - Jaxon Crosmas

2

如果您收到类似问号(Unicode块)的响应,则意味着您的记事本(IDE)以utf8格式显示它,但其数据以另一种格式获取。

为了解决这个问题,我使用了iconv

const { Iconv } = require('iconv');
const convertedXmlResponse = Iconv('windows-1251', 'utf8')
    .convert(dataBuffer)
    .toString();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接