Objective C - 将NSString拆分为Array,最大计数

时间:2013-07-24 15:35:17

标签: objective-c arrays nsstring split

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

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"]

有人有什么想法吗?

2 个答案:

答案 0 :(得分:0)

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

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

上面匹配三个没有冒号的字符序列,用冒号分隔,然后是第四个由任何类型的字符组成的组。前面的^和末尾的$分别匹配字符串的开头和结尾,否则像1:2:3:4:49:DE:Bahnhofsstr:12:39:11这样的无意义会匹配,因为字符串中嵌入了匹配项。< / p>

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

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

以下是如何在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
    }
}

答案 1 :(得分: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];

读取字符串剩余部分的最后一行直接来自docs for NSScanner