我收到了一段代表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世界中的回车,=3D
:HEX 3D
为DEC 61
,这是一个等号:=
,=96
:HEX 96
是DEC 150
,这是一个'en dash'标志:–
(某种“长减号”),=A3
:HEX A3
是DEC 163
,这是一个英镑符号:£
我无法控制HTML的生成,但是我应该解析它并清理它,然后返回£
(而不是=A3
)等。
现在,我知道我可以保留内存映射中的转换,但我想知道是否已经有一个涵盖整个windows-1252
字符集的编程解决方案?
比照。这对于整个转换表:https://www.w3schools.com/charsets/ref_html_ansi.asp
修改
输入HTML来自IMAP会话,所以似乎有一个7bit / 8bit“引用的可打印编码”在上游进行,我无法控制(参见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>
编码字符?
答案 0 :(得分:0)
似乎通过IMAP收到的消息提供了两种不同编码的组合:
<meta>
标记的HTML 这些HTML块还存在“问题”,其中包含Windows样式(\r\n
)中的大量回车。我不得不预先处理字符串以处理它,在我的情况下:删除那些回车。
以下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: –"
请注意在Windows-1252解码阶段之前/之后呈现的“长短划线字符”。
Afaik,这与UTF-8编码/解码无关。我能够从这里找出程序的“解码顺序”:https://github.com/mathiasbynens/quoted-printable/issues/5
我不确定的一件事是我运行这段代码的操作系统是否会对文件或字符串流的字符集/编码产生某种影响。
我使用的npm
个包是: