解码 windows-1252 和引用可打印 HTML 的组合
Decoding a combination of windows-1252 and quoted printable HTML
我收到一段代表 HTML 的文本,例如:
<html>\r\n<head>\r\n<meta http-equiv=3D\"Content-Type\" content=3D\"text/html; charset=3DWindows-1=\r\n252\">\r\n<style type=3D\"text/css\" style=3D\"display:none;\"><!-- P {margin-top:0;margi=\r\nn-bottom:0;} --></style>\r\n</head>\r\n<body dir=3D\"ltr\">This should be a pound sign: =A3 and this should be a long dash: =96 \r\n</body>\r\n</html>\r\n
从 HTML <meta>
标签中我可以看出 HTML 的片段应该被编码为 Windows-1252.
我正在使用node.js来解析这段文字cheerio
。然而用 https://github.com/mathiasbynens/windows-1252 解码它没有帮助: windows1252.decode(myString);
返回相同的输入字符串。
我认为的原因是因为该输入字符串已经在标准 node.js 字符集中编码,但它实际上 表示 一个 windows-1252
编码的片段HTML(是否有意义?)。
检查以 =
开头的那些奇怪的十六进制数字,我可以看到有效的 windows-1252
代码,例如:
- 这个
=\r\n
和这个\r\n
应该代表Windows世界中的马车return,
=3D
: HEX 3D
是 DEC 61
这是一个等号: =
,
=96
:HEX 96
是 DEC 150
,这是一个 'en dash' 符号:–
(某种 "long minus symbol"),
=A3
:HEX A3
是 DEC 163
,这是一个井号:£
我无法控制那段 HTML 的生成,但我应该解析它并清理它并返回 £
(而不是 =A3
)等等
现在,我知道我可以保留一个包含转换的内存映射,但我想知道是否已经有一个涵盖整个 windows-1252
字符集的编程解决方案?
比照。这对于整个转换 table:https://www.w3schools.com/charsets/ref_html_ansi.asp
编辑:
输入 HTML 来自 IMAP 会话,所以似乎有一个 7 位/8 位 "quoted printable encoding" 在上游进行,我无法控制(参见 https://en.wikipedia.org/wiki/Quoted-printable)。
与此同时,我开始意识到这种额外的编码,并且我尝试了这个 quoted-printable
(参见 https://github.com/mathiasbynens/quoted-printable)库,但没有成功。
以下是 MCV(根据要求):
var cheerio = require('cheerio');
var windows1252 = require('windows-1252');
var quotedPrintable = require('quoted-printable');
const inputString = '<html>\r\n<head>\r\n<meta http-equiv=3D\"Content-Type\" content=3D\"text/html; charset=3DWindows-1=\r\n252\">\r\n<style type=3D\"text/css\" style=3D\"display:none;\"><!-- P {margin-top:0;margi=\r\nn-bottom:0;} --></style>\r\n</head>\r\n<body dir=3D\"ltr\">This should be a pound sign: =A3 and this should be a long dash: =96 \r\n</body>\r\n</html>\r\n'
const $ = cheerio.load(inputString, {decodeEntities: true});
const bodyContent = $('html body').text().trim();
const decodedBodyContent = windows1252.decode(bodyContent);
console.log(`The input string: "${bodyContent}"`);
console.log(`The output string: "${decodedBodyContent}"`);
if (bodyContent === decodedBodyContent) {
console.log('The windows1252 output seems the same of as the input');
}
const decodedQp = quotedPrintable.decode(bodyContent)
console.log(`The decoded QP string: "${decodedQp}"`);
之前的脚本产生以下输出:
The input string: "This should be a pound sign: =A3 and this should be a long dash: =96"
The output string: "This should be a pound sign: =A3 and this should be a long dash: =96"
The windows1252 output seems the same of as the input
The decoded QP string: "This should be a pound sign: £ and this should be a long dash: "
在我的命令行上,我看不到长破折号,我不确定如何正确解码所有这些 =<something>
编码字符?
似乎通过 IMAP 接收的消息是结合了 2 种不同的编码:
- 实际字符串是根据 "quoted printable" 编码 (https://en.wikipedia.org/wiki/Quoted-printable) 编码的,因为我认为在通过 IMAP 通道(TCP 套接字)传输该信息时,7 位/8 位映射存在问题连接)
- 内容(电子邮件正文)的逻辑表示 HTML 带有
<meta>
标签和 Windows-1252 字符集
还有一个 "issue" 包含这些 HTML 块,在 Windows 风格 (\r\n
) 中包含大量运输 returns。我必须预处理字符串来处理这个问题,在我的例子中:删除那些回车 returns.
以下 MCV 示例应显示清理和验证表示电子邮件正文的字符串内容的过程:
var quotedPrintable = require('quoted-printable');
var windows1252 = require('windows-1252');
const inputStr = 'This should be a pound sign: =A3 \r\nand this should be a long dash: =96\r\n';
console.log(`The original string: "${inputStr}"`);
// 1. clean the "Windows carriage returns" (\r\n)
const cleandStr = inputStr.replace(/\r\n/g, '');
console.log(`The string without carriage returns: "${cleandStr}"`);
// 2. decode using the "quoted printable protocol"
const decodedQp = quotedPrintable.decode(cleandStr)
console.log(`The decoded QP string: "${decodedQp}"`);
// 3. decode using the "windows-1252"
const windows1252DecodedQp = windows1252.decode(decodedQp);
console.log(`The windows1252 decoded QP string: "${windows1252DecodedQp}"`);
这给出了这个输出:
The original string: "This should be a pound sign: =A3
and this should be a long dash: =96
"
The string without carriage returns: "This should be a pound sign: =A3 and this should be a long dash: =96"
The decoded QP string: "This should be a pound sign: £ and this should be a long dash: "
The windows1252 decoded QP string: "This should be a pound sign: £ and this should be a long dash: –"
注意 "long dash character" before/after Windows-1252 解码阶段的渲染方式不同。
Afaik,这与 UTF-8 encoding/decoding 无关。我能够从中找出程序的"decoding order":https://github.com/mathiasbynens/quoted-printable/issues/5
有一件事我不确定,我使用的操作系统 运行 这段代码是否对 charsets/encodings 文件或字符串流有某种影响。
我用过的npm
包是:
我收到一段代表 HTML 的文本,例如:
<html>\r\n<head>\r\n<meta http-equiv=3D\"Content-Type\" content=3D\"text/html; charset=3DWindows-1=\r\n252\">\r\n<style type=3D\"text/css\" style=3D\"display:none;\"><!-- P {margin-top:0;margi=\r\nn-bottom:0;} --></style>\r\n</head>\r\n<body dir=3D\"ltr\">This should be a pound sign: =A3 and this should be a long dash: =96 \r\n</body>\r\n</html>\r\n
从 HTML <meta>
标签中我可以看出 HTML 的片段应该被编码为 Windows-1252.
我正在使用node.js来解析这段文字cheerio
。然而用 https://github.com/mathiasbynens/windows-1252 解码它没有帮助: windows1252.decode(myString);
返回相同的输入字符串。
我认为的原因是因为该输入字符串已经在标准 node.js 字符集中编码,但它实际上 表示 一个 windows-1252
编码的片段HTML(是否有意义?)。
检查以 =
开头的那些奇怪的十六进制数字,我可以看到有效的 windows-1252
代码,例如:
- 这个
=\r\n
和这个\r\n
应该代表Windows世界中的马车return, =3D
: HEX3D
是 DEC61
这是一个等号:=
,=96
:HEX96
是 DEC150
,这是一个 'en dash' 符号:–
(某种 "long minus symbol"),=A3
:HEXA3
是 DEC163
,这是一个井号:£
我无法控制那段 HTML 的生成,但我应该解析它并清理它并返回 £
(而不是 =A3
)等等
现在,我知道我可以保留一个包含转换的内存映射,但我想知道是否已经有一个涵盖整个 windows-1252
字符集的编程解决方案?
比照。这对于整个转换 table:https://www.w3schools.com/charsets/ref_html_ansi.asp
编辑:
输入 HTML 来自 IMAP 会话,所以似乎有一个 7 位/8 位 "quoted printable encoding" 在上游进行,我无法控制(参见 https://en.wikipedia.org/wiki/Quoted-printable)。
与此同时,我开始意识到这种额外的编码,并且我尝试了这个 quoted-printable
(参见 https://github.com/mathiasbynens/quoted-printable)库,但没有成功。
以下是 MCV(根据要求):
var cheerio = require('cheerio');
var windows1252 = require('windows-1252');
var quotedPrintable = require('quoted-printable');
const inputString = '<html>\r\n<head>\r\n<meta http-equiv=3D\"Content-Type\" content=3D\"text/html; charset=3DWindows-1=\r\n252\">\r\n<style type=3D\"text/css\" style=3D\"display:none;\"><!-- P {margin-top:0;margi=\r\nn-bottom:0;} --></style>\r\n</head>\r\n<body dir=3D\"ltr\">This should be a pound sign: =A3 and this should be a long dash: =96 \r\n</body>\r\n</html>\r\n'
const $ = cheerio.load(inputString, {decodeEntities: true});
const bodyContent = $('html body').text().trim();
const decodedBodyContent = windows1252.decode(bodyContent);
console.log(`The input string: "${bodyContent}"`);
console.log(`The output string: "${decodedBodyContent}"`);
if (bodyContent === decodedBodyContent) {
console.log('The windows1252 output seems the same of as the input');
}
const decodedQp = quotedPrintable.decode(bodyContent)
console.log(`The decoded QP string: "${decodedQp}"`);
之前的脚本产生以下输出:
The input string: "This should be a pound sign: =A3 and this should be a long dash: =96"
The output string: "This should be a pound sign: =A3 and this should be a long dash: =96"
The windows1252 output seems the same of as the input
The decoded QP string: "This should be a pound sign: £ and this should be a long dash: "
在我的命令行上,我看不到长破折号,我不确定如何正确解码所有这些 =<something>
编码字符?
似乎通过 IMAP 接收的消息是结合了 2 种不同的编码:
- 实际字符串是根据 "quoted printable" 编码 (https://en.wikipedia.org/wiki/Quoted-printable) 编码的,因为我认为在通过 IMAP 通道(TCP 套接字)传输该信息时,7 位/8 位映射存在问题连接)
- 内容(电子邮件正文)的逻辑表示 HTML 带有
<meta>
标签和 Windows-1252 字符集
还有一个 "issue" 包含这些 HTML 块,在 Windows 风格 (\r\n
) 中包含大量运输 returns。我必须预处理字符串来处理这个问题,在我的例子中:删除那些回车 returns.
以下 MCV 示例应显示清理和验证表示电子邮件正文的字符串内容的过程:
var quotedPrintable = require('quoted-printable');
var windows1252 = require('windows-1252');
const inputStr = 'This should be a pound sign: =A3 \r\nand this should be a long dash: =96\r\n';
console.log(`The original string: "${inputStr}"`);
// 1. clean the "Windows carriage returns" (\r\n)
const cleandStr = inputStr.replace(/\r\n/g, '');
console.log(`The string without carriage returns: "${cleandStr}"`);
// 2. decode using the "quoted printable protocol"
const decodedQp = quotedPrintable.decode(cleandStr)
console.log(`The decoded QP string: "${decodedQp}"`);
// 3. decode using the "windows-1252"
const windows1252DecodedQp = windows1252.decode(decodedQp);
console.log(`The windows1252 decoded QP string: "${windows1252DecodedQp}"`);
这给出了这个输出:
The original string: "This should be a pound sign: =A3
and this should be a long dash: =96
"
The string without carriage returns: "This should be a pound sign: =A3 and this should be a long dash: =96"
The decoded QP string: "This should be a pound sign: £ and this should be a long dash: "
The windows1252 decoded QP string: "This should be a pound sign: £ and this should be a long dash: –"
注意 "long dash character" before/after Windows-1252 解码阶段的渲染方式不同。
Afaik,这与 UTF-8 encoding/decoding 无关。我能够从中找出程序的"decoding order":https://github.com/mathiasbynens/quoted-printable/issues/5
有一件事我不确定,我使用的操作系统 运行 这段代码是否对 charsets/encodings 文件或字符串流有某种影响。
我用过的npm
包是: