Mat*_*ski 21 javascript regex utf-8
我想从JavaScript中的字符串中删除所有无效的UTF-8字符.我试过这个JavaScript:
strTest = strTest.replace(/([\x00-\x7F]|[\xC0-\xDF][\x80-\xBF]|[\xE0-\xEF][\x80-\xBF]{2}|[\xF0-\xF7][\x80-\xBF]{3})|./g, "$1");
似乎这里描述的UTF-8验证正则表达式(已删除链接)更完整,我以相同的方式调整它:
strTest = strTest.replace(/([\x09\x0A\x0D\x20-\x7E]|[\xC2-\xDF][\x80-\xBF]|\xE0[\xA0-\xBF][\x80-\xBF]|[\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}|\xED[\x80-\x9F][\x80-\xBF]|\xF0[\x90-\xBF][\x80-\xBF]{2}|[\xF1-\xF3][\x80-\xBF]{3}|\xF4[\x80-\x8F][\x80-\xBF]{2})|./g, "$1");
这两段代码似乎都允许有效的UTF-8通过,但是我的测试数据中几乎没有过滤任何坏的UTF-8字符:UTF-8解码器功能和压力测试.要么坏字符没有变化,要么删除了一些字节,从而创建一个新的无效字符.
我不是很熟悉UTF-8标准或JavaScript中的多字节,所以我不确定我是否未能在正则表达式中表示正确的UTF-8,或者我是否在JavaScript中不正确地应用该正则表达式.
编辑:根据Tomalak的评论为我的正则表达式添加了全局标志 - 但是这仍然不适合我.根据bobince的评论,我放弃了在客户端这样做.
Ali*_*Ali 27
我使用这种简单而坚固的方法:
function cleanString(input) {
var output = "";
for (var i=0; i<input.length; i++) {
if (input.charCodeAt(i) <= 127) {
output += input.charAt(i);
}
}
return output;
}
Run Code Online (Sandbox Code Playgroud)
基本上你真正想要的只是ASCII字符0-127所以只需用char重建字符串char.如果这是一个很好的焦炭,保留它 - 如果不是,就放弃它.相当健壮,如果卫生是你的目标,它足够快(实际上它真的很快).
bob*_*nce 20
JavaScript字符串本身就是Unicode.它们保存字符序列*而不是字节序列,因此不可能包含无效的字节序列.
(从技术上讲,它们实际上包含UTF-16代码单元序列,这不是完全相同的东西,但这可能不是你现在需要担心的任何事情.)
如果由于某种原因需要,可以创建一个字符串,其中包含用作字节占位符的字符.即.使用字符U+0080('\ x80')代表字节0x80.如果您使用UTF-8将字符编码为字节,然后使用ISO-8859-1错误地将它们解码回字符,则会获得此结果.这有一个特殊的JavaScript习惯用法:
var bytelike= unescape(encodeURIComponent(characters));
Run Code Online (Sandbox Code Playgroud)
并再次从UTF-8伪字节返回到字符:
var characters= decodeURIComponent(escape(bytelike));
Run Code Online (Sandbox Code Playgroud)
(值得注意的是,这几乎是应该使用escape/ unescape函数的唯一时间.它们在任何其他程序中的存在几乎总是一个bug.)
decodeURIComponent(escape(bytes))因为它的行为类似于UTF-8解码器,如果输入的代码单元序列不能被接受为UTF-8字节,则会引发错误.
您很少需要在JavaScript中处理这样的字节字符串.最好继续在客户端使用Unicode本地工作.浏览器将负责对线路上的字符串进行UTF-8编码(在表单提交或XMLHttpRequest中).
简单的错误,大的影响:
strTest = strTest.replace(/your regex here/g, "$1");
// ----------------------------------------^
Run Code Online (Sandbox Code Playgroud)
如果没有"全局"标志,则仅对第一个匹配进行替换.
旁注:要删除任何不满足某种复杂条件的字符,例如落入一组某些Unicode字符范围,您可以使用否定前瞻:
var re = /(?![\x00-\x7F]|[\xC0-\xDF][\x80-\xBF]|[\xE0-\xEF][\x80-\xBF]{2}|[\xF0-\xF7][\x80-\xBF]{3})./g;
strTest = strTest.replace(re, "")
Run Code Online (Sandbox Code Playgroud)
其中re全文
(?! # negative look-ahead: a position *not followed by*: […] # any allowed character range from above ) # end lookahead . # match this character (only if previous condition is met!)
如果你试图从javascript字符串中删除"无效字符" - - 那么你可以像这样摆脱它们:
myString = myString.replace(/\uFFFD/g, '')
Run Code Online (Sandbox Code Playgroud)
西班牙语和法语等语言有重音字符,如“é”,代码在 160-255 范围内,请参阅https://www.ascii.cl/htmlcodes.htm
function cleanString(input) {
var output = "";
for (var i=0; i<input.length; i++) {
if (input.charCodeAt(i) <= 127 || input.charCodeAt(i) >= 160 && input.charCodeAt(i) <= 255) {
output += input.charAt(i);
}
}
return output;
}
Run Code Online (Sandbox Code Playgroud)