如何去除utf-8字符串里头的非法字符

在开发的过程中碰到了在utf-8的字符串里头有非法字符的问题,搜了下,有不少人遇到了相同的问题。

有种方法是使用iconv,iconv.open("UTF-8", UTF-8//IGNORE"),由于要处理的字符长度变化幅度大,每次转换需要分配的内存比较大,同时还需要清零,比较费时。

另外观察感觉iconv本身比较耗时,所以寻求其他简单的方法。

综合stackoverflow的帖子,方法如下。

Table 3-7. Well-Formed UTF-8 Byte Sequences

Code Points        First Byte Second Byte Third Byte Fourth Byte
U+0000..U+007F     00..7F
U+0080..U+07FF     C2..DF     80..BF
U+0800..U+0FFF     E0         A0..BF      80..BF
U+1000..U+CFFF     E1..EC     80..BF      80..BF
U+D000..U+D7FF     ED         80..9F      80..BF
U+E000..U+FFFF     EE..EF     80..BF      80..BF
U+10000..U+3FFFF   F0         90..BF      80..BF     80..BF
U+40000..U+FFFFF   F1..F3     80..BF      80..BF     80..BF
U+100000..U+10FFFF F4         80..8F      80..BF     80..BF

int correct_non_utf_8(string *str){
    int i,f_size=str->size();
    unsigned char c,c2,c3,c4;
    string to;
    to.reserve(f_size);
    //~ size_t pos = from->find("'advsearch': ' Avansert s");

    for(i=0 ; i<f_size ; i++){
        c=(unsigned char)(*str)[i];
        if(c<32){//control char         
            if(c==9 || c==10 || c==13){//allow only \t \n \r
                to.append(1,c);
            }
        }else if(c<127){//normal ASCII
            to.append(1,c);
        }else if(c<160){//control char
            if(c2==128){//fix microsoft mess, add euro
                to.append(1,226);
                to.append(1,130);
                to.append(1,172);
            }
            if(c2==133){//fix IBM mess, add NEL = \n\r
                to.append(1,10);
                to.append(1,13);
            }
        }else if(c<192){//invalid for UTF8, converting ASCII
            to.append(1,(unsigned char)194);
            to.append(1,c);
        }else if(c<194){//invalid for UTF8, converting ASCII
            to.append(1,(unsigned char)195);
            to.append(1,c-64);
        }else if(c<224){//possibly 2byte UTF8
            c2=(unsigned char)(*str)[i+1];
            if(c2>127 && c2<192){//valid 2byte UTF8
                if(c==194 && c2<160){//control char, skipping
                    ;
                }else{
                    to.append(1,c);
                    to.append(1,c2);                    
                }
                i++;
            }else{//invalid UTF8, converting ASCII
                to.append(1,(unsigned char)195);
                to.append(1,c-64);
            }
        }else if(c<240){//possibly 3byte UTF8
            c2=(unsigned char)(*str)[i+1];
            c3=(unsigned char)(*str)[i+2];
            if(c2>127 && c2<192 && c3>127 && c3<192){//valid 3byte UTF8
                to.append(1,c);
                to.append(1,c2);
                to.append(1,c3);
                i+=2;
            }else{//invalid UTF8, converting ASCII
                to.append(1,(unsigned char)195);
                to.append(1,c-64);
            }
        }else if(c<245){//possibly 4byte UTF8
            c2=(unsigned char)(*str)[i+1];
            c3=(unsigned char)(*str)[i+2];
            c4=(unsigned char)(*str)[i+3];
            if(c2>127 && c2<192 && c3>127 && c3<192 && c4>127 && c4<192){//valid 4byte UTF8
                to.append(1,c);
                to.append(1,c2);
                to.append(1,c3);
                to.append(1,c4);
                i+=3;
            }else{//invalid UTF8, converting ASCII
                to.append(1,(unsigned char)195);
                to.append(1,c-64);
            }
        }else if(c<256){//invalid UTF8, converting ASCII
            to.append(1,(unsigned char)195);
            to.append(1,c-64);
        }else{
            cout<<"WTF? more than 256 values per Byte ? ("<<(unsigned int)c<<")"<<endl;
        }
    }
    *str=to;
    return 1;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值