Json去除非法字符(从UTF-8编码方向)

公司的一个老项目中,总是因为json解析失败导致界面无法正常显示,导致客户工作无法正常展开。刚开始以为是各种转义符的原因,把转义符去掉之后偶尔还会出现,从后台数据库发现是特别奇怪的字符,根本没有见过,怎么办,输入法根本打不出来,没法像转义符那样替换掉,还有就算这个字符能够替换掉,要是出现其它的字符,还得重新搞。思考有没有一个办法一次性去掉所有的,有了,尝试着从UTF-8编码方向搞。

然后就是各种查,百度,根本没找到,那就查UTF-8编码表,找来找去将要放弃的时候终于在Wiki上找到了UTF-8编码表。突破点已经有了。

通过编码表中字符所对应的值来判断,取想要的字符,去掉不能解析的字符

上代码


NSString *json = @"{\"key\":\"!@#¥%……&*()——+~|、】【,。、?“:;‘?\"}";

NSData *jsonData = [json dataUsingEncoding:NSUTF8StringEncoding];

NSString *utf8Encode = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];

NSMutableString *appendStr = [NSMutableString string];

for(int i =0; i < [utf8Encode length]; i++) {

//编码表字符所对应的10进制值

unsigned long character = (unsigned long)[utf8Encode characterAtIndex:i];

//字符

NSString *str = [utf8Encode substringWithRange:NSMakeRange(i, 1)];

//取范围内的值

if ((character > 0x0020u && character < 0x007Fu && character != 0x005Cu) ||

(character >= 0x2000u && character < 0xA000u) ||

(character >= 0xF900u && character < 0x10000u)) {

[appendStr appendString:str];

} else {

//打印不在范围内的字符和值

NSLog(@"error str:%@,%lu",str,character);

}

}

那思路是取能被正确解析的字符添加到新创建的appendStr中。这里代码是尽可能缩小了范围。character > 0x0020u && character < 0x007Fu && character != 0x005Cu排除了各种转义符,character >= 0x2000u && character < 0xA000u是CJK的范围,character >= 0xF900u && character < 0x10000u中包含中文标点符号。具体请看UTF-8编码表。

下面的代码尽可能的扩大了范围

/*
 这里是其他的文字,可以测试
 Latin:Iūnō    IPA:ɐɷɸ    accents: ᪱◌᷁◌︤ Greek:Πͷἧᾘ Cyril:йЖӜ
 Armeni:վտրցւփ  Hebrew:  ֦ ‎ Arabic: ڤ ڴ ڕ   Syriac:ܧܔ܊
 Thaana:ޓޔޕ    N'Ko:ߘ‎߆‎߷‎   Kana:さサぬヌ    Hangul:ㅂㅒㅢ
 */

if ((character > 0x0020u && character < 0x007Fu && character != 0x005Cu) ||
    (character >= 0x0120u && character < 0x0800u) ||
    (character >= 0x1000u && character < 0xD000u) ||
    (character >= 0xE000u && character < 0x10000u) ||
    (character >= 0x40000u && character < 0x100000u)) {

    [appendStr appendString:str];

} else {
    DPLog(@"error str:%@,%lu",str,character);
}

现在已经得到了自己想要的字符串,但是还有一个问题,json中{"key":"value"} 的value内容可能会包含双引号",这会导致解析失败。

很简单,通过判断"前后是不是{[:]},来区分json格式和value内容中的"(因为前面我们已经把空格、换行符等去掉了,不会把json格式的"去掉)

代码来了

//去除双引号"
NSMutableString *validJson = [NSMutableString stringWithString:appendStr];
NSMutableArray *rangeArr = [NSMutableArray arrayWithCapacity:0];
for (int i = 0; i < validJson.length - 1; i ++) {
    
    NSRange range = NSMakeRange(i, 1);
    NSString *character = [validJson substringWithRange:range];
    if ([character isEqualToString:@"\""]) {
        NSString *preCharacter = [validJson substringWithRange:NSMakeRange(i-1, 1)];
        NSString *subCharacter = [validJson substringWithRange:NSMakeRange(i+1, 1)];
        NSString *condition = @"{[:]},";
        BOOL pre = [condition rangeOfString:preCharacter].location == NSNotFound;
        BOOL sub = [condition rangeOfString:subCharacter].location == NSNotFound;
        if (pre && sub) {
            //说明是单" 消灭它
            NSValue *value = [NSValue valueWithRange:range];
            [rangeArr addObject:value];
        }
    }
}

//rangeArr reverse
rangeArr = (NSMutableArray *)[[rangeArr reverseObjectEnumerator] allObjects];

//消灭它
for (NSValue *value in rangeArr) {
    NSRange range = [value rangeValue];
    [validJson deleteCharactersInRange:range];
}

好了,到这里就已经完了,json中不能正常解析的字符就被我们清除了!✌️

下面是通过值打印字符的小东西,不过有点问题,能够勉强帮助我们一下。有谁知道解决办法的请留言

NSUInteger length = 0xFFFF - 0xF000;
unichar uni[length];
for(unichar i = 0xF000; i < 0xFFFF; i++) {
    uni[i - 0xF000] = i;
}
NSString *testChar = [[NSString alloc] initWithCharacters:uni length:length];
NSLog(@"testChar: %@",testChar);
如果文章中有错误,请留言指出!

你可能感兴趣的:(Json去除非法字符(从UTF-8编码方向))