解析具有特定格式的字符串

时间:2013-07-19 00:29:53

标签: objective-c format

我有一个关于使用目标C解析字符串的快速问题。目前,我有一个输出* A_1_2_3_4_~的格式。该字符串具有消息开头(*),标题(A),值(1)和消息结束(〜)。我已经为arduino编写了这段代码,但似乎无法让它在目标c中正常工作。该函数的作用是将每个值分开并对其进行分类。非常高效和坚固。如果我发送* A_1_1_1_~,则会识别出A代表的是某个值,值为1,1,1。无论如何,这里代码为:

//protocol for parsing
-(void)protocol:(NSString*)input type:(Boolean*)comType
{
    Byte place = 0, index, ID, average, setGet; //any value < 256
    int probeType, tempType;
    char Header;
    NSString *output; //used for parsing
    double probeValue, tempValue;

//    if(comType){}
//    //wire = ""; //reset wire
//    else
//        analog.text = @"";//serial = ""; //reset serial

    //if error in message example: A_1_1_A_1_A_A_A*A_1_1_8.27_1_15.67_3_~
    //use '*' as start of message character and grab from *A_1_1_8.27_1_15.67_3_~

    probeType = input.length; //get length of string

    index = [input rangeOfString:@"*" options:NSBackwardsSearch].location; //index = input.lastIndexOf("*"); //index contains start of message
    if(index < 0)  //not available or incorrect format
        return;
    input = [input substringFromIndex:index]; //remove incorrect stuff
    average = [input rangeOfString:@"~"].location; //input.indexOf("~", index); //grab end of message
    input = [input substringWithRange:NSMakeRange(index+1, average+index)]; //input = input.substring(index + 1, average + 1); //grab valid string only, lower bandwidth
    //    [self alert: input];
    for(Byte i = 0; i < 8; i++) //limit the message length as well
    {
        //        index = [input rangeOfString:@"_"].location; //grab location of
        index = [input rangeOfString:@"_" options:Nil range:NSMakeRange(place, input.length)].location;//index = input.indexOf("_", place); //gets first update
        //        [self alert:index];
        if(index < 0 || [input characterAtIndex:index+1] == '~')//input.substring(place, index + 1) == "~") //no '_' found or EOM
            break; //two birds one stone
        output = [input substringWithRange:NSMakeRange(place, index)];//output = input.substring(place, index); //grab in between
        //input = [input stringByReplacingCharactersInRange:NSMakeRange(0, index) withString:@""];//remove already read

        switch(i)
        {
            case 0: //header
                Header = [output characterAtIndex:0]; //fast conversion from String to char
                break;
            case 1: //ID
                ID = [output intValue]; //toInt() returns long...not int; perfect for conductivity
                break;
            case 2: //Probe Type
                probeType = [output intValue];
                break;
            case 3: //Probe Value
                probeValue = [output doubleValue];
                break;
            case 4: //Temperature Type
                tempType = [output intValue];
                break;
            case 5: //Temperature Value
                tempValue = [output doubleValue];
                break;
            case 6: //Average
                average = [output intValue];
                break;
            case 7:
                setGet = [output intValue];
                break;
        }
        place = index + 1;
        [self alert: output];
    }
}

2 个答案:

答案 0 :(得分:1)

目前尚不清楚所有参数对于格式的外观是什么,但我会这样做以从字符串中提取数字。就像你的问题一样,我在字符串中查找第一个“*”,从末尾向后搜索。

 - (void)viewDidLoad {

    [super viewDidLoad];
    NSCharacterSet *nonNumbers = [[NSCharacterSet characterSetWithCharactersInString:@"0123456789."] invertedSet];
    NSString *s = @"A_1_1_A_1_A_A_A*A_1_1_8.27_1_15.67_3_~"; // test string
    NSInteger locationOfAsterisk = [s rangeOfString:@"*" options:NSBackwardsSearch].location;
    if (locationOfAsterisk != NSNotFound) {
        NSString *validString = [s substringFromIndex:locationOfAsterisk + 1];
        NSMutableArray *parsedArray = [[s componentsSeparatedByString:@"_"] mutableCopy];
        NSIndexSet *indxs = [parsedArray indexesOfObjectsPassingTest:^BOOL(NSString *obj, NSUInteger idx, BOOL *stop) {
            return [obj rangeOfCharacterFromSet:nonNumbers].location != NSNotFound ;
        }];
        [parsedArray removeObjectsAtIndexes:indxs];
        [parsedArray insertObject:[validString substringToIndex:1] atIndex:0];
        NSLog(@"%@",parsedArray);

    }else{
        NSLog(@"Not a valid format");
    }
}

这将返回一个数组,第一个元素是星号后面的字母,后跟所有数字,直到代字号。

答案 1 :(得分:0)

//protocol for parsing
-(void)protocol:(NSString*)inputString type:(Boolean*)comType
{
    int probeType, tempType, index, ID, average, setGet;
    NSMutableString *Header;
//    NSString *output; //used for parsing
    double probeValue, tempValue;

    //if error in message example: A_1_1_A_1_A_A_A*A_1_1_8.27_1_15.67_3_~
    //use '*' as start of message character and grab from *A_1_1_8.27_1_15.67_3_~

    probeType = inputString.length; //steal probeType for now, probeType contains length of string

    index = [inputString rangeOfString:@"*" options:NSBackwardsSearch].location; //index contains SoM, index
    if(index < 0)  //not available
        return;
    inputString = [inputString substringFromIndex:index]; //remove incorrect stuff before SoM
    average = [inputString rangeOfString:@"~"].location; //grab end of message
    inputString = [inputString substringWithRange:NSMakeRange(index+1, average)]; //grab valid string from SoM with length
    inputString = [inputString stringByReplacingOccurrencesOfString:@"*" withString:@""]; //need to remove *
    inputString = [inputString stringByReplacingOccurrencesOfString:@"~" withString:@""]; //need to remove ~
    NSMutableArray *arrayOfNumbers = [[inputString componentsSeparatedByString:@"_"] mutableCopy]; //

    int objects = [arrayOfNumbers count]; //no need for ~ sign

    for(int i = 0; i < objects; i++) //limit the message length as well
    {
        switch(i)
        {
            case 0: //header
                Header = [arrayOfNumbers objectAtIndex:i]; //[output characterAtIndex:0]; //fast conversion from String to char
                break;
            case 1: //ID
                ID = [[arrayOfNumbers objectAtIndex:i] intValue]; //[output intValue]; //toInt() returns long...not int; perfect for conductivity
                break;
            case 2: //Probe Type
                probeType = [[arrayOfNumbers objectAtIndex:i] intValue];
                break;
            case 3: //Probe Value
                probeValue = [[arrayOfNumbers objectAtIndex:i] doubleValue];
                break;
            case 4: //Temperature Type
                tempType = [[arrayOfNumbers objectAtIndex:i] intValue];
                break;
            case 5: //Temperature Value
                tempValue = [[arrayOfNumbers objectAtIndex:i] doubleValue];
                break;
            case 6: //Average
                average = [[arrayOfNumbers objectAtIndex:i] intValue];
                break;
            case 7:
                setGet = [[arrayOfNumbers objectAtIndex:i] intValue];
                break;
        }
        [self alert: [arrayOfNumbers objectAtIndex:i]];
    }
}