自己动手解Json!(IOS利用分治法解析Json)(二)

  第一篇的链接为  自己动手解Json!(IOS利用分治法解析Json)(一)


  好了,我们知道,写程序需要一步一步的来,我们今天的任务就是要把   {\"name\":\"zhangsan\",\"age\":26 }  

这个Json数据解析成NSDictionary对象 (加入的\是转义字符,因为在字符串中"字符是包裹字符用的,

在"的前面加\程序才知道这个"是字符串中的",而不是用来包裹整个字符串的)

 在上一篇中,我们已经抽象出来根据传入的Json字符串与开始寻找的位置,给出下一个所需要查找的字符出现的位置  的方法,

在上述Json字符串中,我们发现,值虽然有字符串对象也有数字,但键都是字符串对象,所以,

我们可以有一个根据传入的Json字符串与开始寻找的位置,找到第一个key值和包裹key值的第二个"的位置,并添加到数组中返回的方法

 那么我们为什么要在找到key值的同时还要返回第二个"的位置呢,因为我们知道,程序在解析Json的时候,肯定是循环调用的 基本思路就是 

先找到key值,在key值的后面找到value,然后在寻找下一个key  

 我们在找到key后,也需要判断value的类型,如何判断呢,可以通过包裹key值的第二个"的位置在加2后截取的字符串来判断,如果是数字,那么value就是数字,如果是",那么value就是字符串... 

 但是我们不是也可以只返回一个key值,然后在根据第一个"的位置加上key值的length就能找到了吗,别忘了,一个还行,如果很多的话,就会有重复代码的问题,这是所有程序员,程序都要避免的问题


  分析完了,上代码吧

 

/*
 
 根据传入的Json字符串与开始寻找的位置,找到第一个key值和包裹key值的第二个"的位置,并添加到数组中返回
 
 开始寻找的位置应该是包裹key值的第一个"的位置,所以beginPostion就是第一个"的位置
 eg:
    {"name":"zhangsan"}  ,那么将会返回 name 和 name 后的"在string中的位置
    即array[0]是name array[1]是6
 */
- (NSArray *) findKeyFromString:(NSString *)dicJsonString beginPostion:(int) beginPostion{
    
    //找到包裹key值的第二个"的位置,即从第一个"的下一个字符处开始寻找
    int nextSignPostion = [self searchNextSign:'"' formString:dicJsonString beginPostion:beginPostion+1];
    
    //计算出需要截取的长度
    int subLenght = nextSignPostion - beginPostion - 1;
    
    //寻找的key值
    NSString * key;
    
    //如果是0的话,那么说明""中间没有数据,那么key值是@""
    if (subLenght==0) {
        
        key=@"";
        
    }else{
        
        NSRange range = NSMakeRange(beginPostion+1 , subLenght);
        
        //截取出相应的key
        key = [dicJsonString  substringWithRange:range];
        
    }
     
    //将下一个"的位置封装成NSNumber Object类型
    NSNumber * nextPostion = [NSNumber numberWithInt:nextSignPostion];
    
    NSArray * keyArray=[NSArray arrayWithObjects:key,nextPostion ,nil];
    
    
    return keyArray;
}


那么接下来就能写解析测试字符串的测试程序了,需要注意今天我们只需要考虑value是数字或者value是字符串两种情况

寻找key和确定其value类型的方法前面已给出

还有需要注意的是,数组中会有一个指针从头开始向后移动得到key和value,当得到value后,指针会指向value的后一个字符,如果字符是},说明指针指向了最后,那么遍历结束,返回获取的总NSMutableDictionary

代码(代码中有详细解释)

/*
 传入一个NSString类型的Json对象, 将其解析成一个NSMutableDictionary返回
 */
-(NSMutableDictionary *) decodeDicString:(NSString *)dicJsonString{
    
    //初始化一个Dic数组
    NSMutableDictionary * decodeDic=[[NSMutableDictionary alloc] init];
    
    //初始位置是指向第一个{
    int postion = 0;
    
    long length = [dicJsonString length];
    
    //当postion不指向最后一个},即未到达最后的时候
    while (postion!=length-1) {
        
        //先寻找key
        NSArray * array = [self findKeyFromString:dicJsonString beginPostion:postion+1];
        
        NSString * key = array[0];
        
        NSNumber * nextPostion = array[1];
        
        
        //找到value中第一个字符的位置,应该是key中第二个"+2的位置
        int valueFirstPostion = nextPostion.intValue+2;
        
        int valueLastPostion;
        
        //截取:之后的第一个字符,看看是数字,还是",
        char fristValue = [dicJsonString characterAtIndex:valueFirstPostion];
        
        //如果是数字的话
        if (fristValue>=48&&fristValue<=57) {
            
            //先从:后面的开始寻找,先找,如果找到,中间即是数字,如果找不到就说明是最后一个,开始寻找}
            valueLastPostion = [self searchNextSign:',' formString:dicJsonString beginPostion:valueFirstPostion];
            
            //如果是-1,说明没找到,这个数是在整个{}的最后面,所以应该valueLastPostion就是长度
            //注意长度是从1开始计算的,所以最后一个是长度减1
            if (valueLastPostion==-1) {
                valueLastPostion = (int) length-1;
            }
            
            //得到其中的数据
            int intValue =  [[dicJsonString substringWithRange:NSMakeRange(valueFirstPostion, valueLastPostion - valueFirstPostion)] intValue];
            
            //添加到NSMutableDictionary中
            [decodeDic setObject:[NSNumber numberWithInt:intValue] forKey:key];
            
            //因为是数字,直接指向了数字后面的,号
            postion = valueLastPostion;
            
            
        }
        //如果是"的话,那么肯定是字符串
        //那么就可以取巧根据寻找key的那个方法来寻找出String类型的value
        else if (fristValue=='"'){
            
            NSArray * stringValueArray = [ self findKeyFromString:dicJsonString beginPostion:valueFirstPostion];
            
            NSString * stringValue = stringValueArray[0];
            
            //第二个"的位置
            valueLastPostion = [stringValueArray[1] intValue];
            
            //添加到NSMutableDictionary中
            [decodeDic setObject:stringValue  forKey:key];
            
            //应指向第二个"后面的,或者}
            postion = valueLastPostion +1;
            
            
        }
        
        
    }
    
    
    return decodeDic;
}


将此篇博客中的两段代码和上篇博客的一段代码复制到类中,在主方法中调用 decodeDicString:( NSString *)dicJsonString 方法,即可解析相关Json字符串

例如此篇博客头部提到的测试字符串 {\"name\":\"zhangsan\",\"age\":26 } 

测试代码:

  NSMutableDictionary * dic = [self decodeDicString:@"{\"name\":\"zhangsan\",\"age\":26 }"];
    
  NSLog(@"解析的结果是%@",dic);

测试结果;

解析的结果是{

    age = 26;

    name = zhangsan;

}




 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值