0

我是 Objective-C 的新手,所以我试图以这种格式将一个字符串拆分为一个数组:

NSString *str = @":49:DE:Bahnhofsstr:12:39:11";
NSArray *arr = [str componentsSeparatedByString:@":"];

我收到以下对象arr

[@"", @"49", @"DE", @"Bahnhofsstr", @"12", @"39", @"11"]

但我需要这种格式:

[@"", @"49", @"DE", @"Bahnhofsstr:12:39:11"]

有人有想法么?

4

2 回答 2

0

JeremyP 提出的正则表达式是解决此类问题的明显方法。

但是,有些人不喜欢正则表达式,因此另一种解决方案是使用NSScanner它也可以扫描字符串并将结果读入变量。鉴于所有字段的分隔符都是相同的,它甚至可以使用漂亮的循环,减少繁琐的扫描代码。

这是一个例子:

NSString *str = @":49:DE:Bahnhofsstr:12:39:11";
const NSUInteger nFields = 4;

NSScanner *myScanner = [NSScanner scannerWithString: str];
NSMutableArray *arr  = [NSMutableArray array];

for (NSUInteger i = 0; i < nFields - 1; i++) {
    NSString *field;

    // The BOOLs here really ought to be checked
    BOOL found  = [myScanner scanUpToString: @":" intoString: &field];
    BOOL passedDelimiter  = [myScanner scanString: @":" intoString: NULL];

    [arr addObject: field ?: @"" ];
}

NSString *lastField = [[myScanner string] substringFromIndex:[myScanner scanLocation]];
[arr addObject: lastField];

读取字符串其余部分的最后一行直接取自.NSScanner

于 2013-07-24T16:19:56.700 回答
0

您可以使用正则表达式。你想要的是这个:

^([^:]*):([^:]*):([^:]*):(.*)$

上面匹配三个不带冒号的字符序列,用冒号分隔,然后是由任何类型的字符组成的第四组。at the ^front 和 the $end 分别匹配字符串的开头和结尾,否则 1:2:3:4:49:DE:Bahnhofsstr:12:39:11会匹配,因为字符串中嵌入了匹配项。

括号分隔捕获组,一旦正则表达式匹配完成,这些组将返回给您。第一个捕获组是第一个冒号之前的所有字符。第二个捕获组是第一个和第二个冒号之间的所有字符。第三个捕获组是第二个和第三个冒号之间的所有字符,第四个捕获组是第三个冒号之后的所有字符。

还有第零个捕获组,它是整个匹配序列。

以下是如何在 Objective-C 中使用它:

NSString* pattern = @"^([^:]*):([^:]*):([^:]*):(.*)$";
NSString* line = @":49:DE:Bahnhofsstr:12:39:11";

NSRegularExpression* regex = [NSRegularExpression regularExpressionWithPattern: pattern
                                                                       options: 0
                                                                         error: &error];
if (regex == nil)
{
    NSLog(@"Invalid regular expression %@, %@", pattern, error);
}
else
{
    NSArray* matches = [regex matchesInString: line
                                      options: 0
                                        range: NSMakeRange(0, [line length])];
    if ([matches count] == 1)
    {
        // Should only be one match
        NSTextCheckingResult* result = [matches objectAtIndex: 0];
        NSMutableArray* captureGroups = [[NSMutableArray alloc] init];
        // Omit capture group 0 because it will be the whole string
        for (int i = 1 ; i < [result numberOfRanges] ; i++)
        {
            NSRange groupRange = [result rangeAtIndex: i];
            NSString* captureGroup = [line substringWithRange: groupRange];
            [captureGroups addObject: captureGroup];
        }
        NSLog(@"The fields are %@", captureGroups);
    }
    else
    {
        // match error
    }
}
于 2013-07-24T16:02:02.837 回答