用户可以将内容复制并粘贴到textarea html输入框中,有时会粘贴无效的UTF-8字符,例如从包含制表符的RTF文件中复制和粘贴。
如何检查一个字符串是否是有效的UTF-8?
用户可以将内容复制并粘贴到textarea html输入框中,有时会粘贴无效的UTF-8字符,例如从包含制表符的RTF文件中复制和粘贴。
如何检查一个字符串是否是有效的UTF-8?
我认为你误解了“UTF-8字符”的意思;UTF-8是Unicode的一种编码方式,可以表示(不断增长的)Unicode标准中定义的任何字符、字形和字母单元。Unicode代码点比可能的UTF8字节值少,因此唯一的“无效UTF8字符”是UTF8字节序列,它们没有映射到任何Unicode代码点,但我假设这不是你所指的。
例如,从包含制表符的rtf文件中复制和粘贴。
RTF是一种独立于底层编码方案的格式化系统,你可以在ASCII、UTF-8、UTF-16和其他编码中使用RTF。关于你帖子中的HTML文本框,HTML中的<input type="text">
和<textarea>
元素只支持纯文本,因此任何RTF格式都会在用户粘贴时自动删除,这就是为什么JS-heavy“rich-edit”和contenteditable
组件在Web应用程序中很常见,尽管在这个答案中,我假设您没有在网页中使用富文本编辑器组件。
RTF文件中的制表符不是RTF功能:它们只是普通的 ASCII-style tab characters,即\t
或0x09
,它们也出现在Unicode中,因此可以出现在UTF-8编码的文本中;此外,Web浏览器允许用户将它们粘贴到<input>
和<textarea>
中也是完全有效的。
Javascript(ECMAScript)本身是Unicode本地化的;也就是说,ECMAScript规范确实要求JS引擎在某些地方使用UTF-16表示,例如在抽象操作IsStringWellFormedUnicode
中:
7.2.9静态语义学:
IsStringWellFormedUnicode
抽象操作
IsStringWellFormedUnicode
接受参数字符串(一个String
),并返回一个Boolean
。 它将字符串解释为UTF-16编码的代码点序列,如6.1.4所述,并确定它是否是格式良好的UTF-16序列。
...但是规范的那一部分是为JS引擎程序员而设计的,而不是为在浏览器中编写JS的人设计的-实际上,我认为可以安全地假设,在Web浏览器中,任何和所有JS string
值将始终是有效的字符串,可以始终被序列化为UTF-8和UTF-16,而且JS脚本不应关心字符串内容的实际内存编码。
所以,考虑到你的问题是这样写的:
用户可以复制并粘贴HTML输入到文本区域,并且有时会粘贴无效的UTF-8字符,例如从包含选项卡的RTF文件复制和粘贴。
如何检查一个字符串是否是有效的UTF-8?
我将其解释为:
一个用户可以从类似WordPad的程序中复制RTF文本,并将其粘贴到Web浏览器中的HTML<textarea>
或<input type="text">
中,当它被粘贴时,RTF的纯文本表示仍然包含应用程序不应接受的某些字符,例如制表符之类的空格。
如何检测这些不需要的字符并通知用户-或删除这些不需要的字符?
...对此我的答案是:
我建议使用匹配非可见字符的正则表达式来剥离不需要的字符(从这里:Match non printable/non ascii characters and remove from text)。
let textBoxContent = document.getElementById( 'myTextarea' ).value;
textBoxContent = textBoxContent.replace( /[^\x20-\x7E]+/g, '' );
表达式[^\x20-\x7E]
匹配任何不在代码点范围内的字符0x20
(32,普通空格字符' '
)到0x7E
(127,波浪符'~'
字符),所有其他字符都将被删除,包括非拉丁文本。
末尾的g
开关使其成为全局查找和替换操作;如果没有g
,则只会删除第一个不需要的字符。
范围0x20-0x7E
有效,因为Unicode的前127个代码点与ASCII相同,可以在此处查看:http://www.asciitable.com/
一个想法:
function checkUTF8(text) {
var utf8Text = text;
try {
// Try to convert to utf-8
utf8Text = decodeURIComponent(escape(text));
// If the conversion succeeds, text is not utf-8
}catch(e) {
// console.log(e.message); // URI malformed
// This exception means text is utf-8
}
return utf8Text; // returned text is always utf-8
}
escape
已被弃用,不应再使用它(因为它无法正确处理 Unicode)。 - Quentin