又一个NSScanner characterSetWithCharactersInString newb

时间:2012-09-12 06:32:49

标签: objective-c nsscanner

假设我有一个字符串(“G00 X0.0000 Y0.0000”),我需要解析其内容。这是我的代码:

NSCharacterSet *params = [NSCharacterSet characterSetWithCharactersInString:@"XY"];

//setup the scanner
NSScanner *scanner = [NSScanner scannerWithString:stringToBeScanned];
NSString *scanned = nil;

//scan the string
NSLog(@"%@", stringToBeScanned);
while ([scanner scanUpToCharactersFromSet:params intoString:&scanned]) {

    struct keypair code;
    code.key = [scanned characterAtIndex:0];
    code.value = [[scanned substringFromIndex:1] doubleValue];

    NSLog(@"--> %@ [%lu]= (%c, %.4f)", scanned, [scanner scanLocation], code.key, code.value);
}

输出到NSLog:

G00 X0.0000 Y0.0000 
--> G00  [4]= (G, 0.0000)

我的characterSet包含'X'和'Y',我无法弄清楚为什么我的NSScanner不会在'X0.0000'中扫描 - 它应该找到Y并从X到Y拉入所有内容根据我的理解。

我可以从scanLocation看到扫描程序在索引4(正确)停止,但循环不会继续或评估为false。扫描仪不应该保持循环并找到我的分隔符(来自characterSet)并抓取数据吗?

2 个答案:

答案 0 :(得分:0)

scanUpToCharactersFromSet:intoString:扫描最多“X”,并为您提供扫描的字符“G00”。

请注意,它不扫描“X”。当您再次调用该方法时,它会查看下一个字符(“X”),注意到它是集合中的字符,并停止扫描。由于它没有扫描任何字符,因此返回NO

要扫描“X”(或“Y”),您还需要使用scanCharactersFromSet:intoString:

答案 1 :(得分:0)

我解决了这个问题。基本上我收到一个字符串,其中包含“代码”列表,后跟与该命令/参数关联的值。每个字符串中可能有几个不同的“命令”,或者根本没有。关键是使用scanCharactersFromSet:和scanUpToCharactersFromSet:以捕获正确的配对并解析整个字符串,同时保持非常灵活。我知道,这有点难看。

这是我的代码:

//setup the scanner
NSScanner *scanner = [NSScanner scannerWithString:[self stringByAppendingString:@"!"]];
NSCharacterSet *codeset = [NSCharacterSet characterSetWithCharactersInString:@"GMTFIJKPRSXYZ!"];
NSString *scanned = nil;
char codechar;

//perform the first scan
[scanner scanCharactersFromSet:codeset intoString:&scanned];
if (scanned)
    codechar = [scanned characterAtIndex:0];

//scan the string
while ([scanner scanUpToCharactersFromSet:codeset intoString:&scanned]) {
    struct keypair code;
    code.key = codechar;
    code.value = [scanned doubleValue];

    NSLog(@"--> (%c, %.4f)", code.key, code.value);

    //skip over the delimeter we encountered
    [scanner scanCharactersFromSet:codeset intoString:&scanned];
    if (scanned)
        codechar = [scanned characterAtIndex:0];

}