NSString:从逗号分隔的NSString中提取字符串

时间:2013-04-24 22:17:03

标签: ios objective-c nsstring

下面是两个用逗号分隔的字符串示例,我将其作为结果返回:

NSString *placeResult = @"111 Main Street, Cupertino, CA"

或有时结果包含地点的名称:

NSString *placeResult = @"Starbucks, 222 Main Street, Cupertino, CA"

检查上面的字符串以查看它是以名称还是街道地址开头的最佳方法是什么?

如果它以名称开头(即上面第二个例子中的星巴克“),我想提取名称并将其存储到另一个变量中。因此在提取后字符串将是:

NSLog (@"%s", placeResult);

日志将打印:

"222 Main Street, Cupertino, CA" 

另一个字符串现在将@“星巴克”存储在其中:

NSLog (@"%s", placeName);

日志将打印:

"Starbucks" 

重要提示:提取后我不能丢失逗号分隔。

谢谢!

2 个答案:

答案 0 :(得分:5)

利用NSDataDetectorNSTextCheckingResult

NSDataDetector *detector = [NSDataDetector dataDetectorWithTypes:NSTextCheckingTypeAddress error:nil];
NSString *str = @"Starbucks, 222 Main Street, Cupertino, CA";
NSArray *matches = [detector matchesInString:str options:0 range:NSMakeRange(0, str.length)];
for (NSTextCheckingResult *match in matches) {
    if (match.resultType == NSTextCheckingTypeAddress) {
        NSDictionary *data = [match addressComponents];
        NSLog(@"address = %@, range: %@", data, NSStringFromRange(match.range));

        NSString *name = data[NSTextCheckingNameKey];
        if (!name && match.range.location > 0) {
            name = [str substringToIndex:match.range.location - 1];
            // "name" may now include a trailing comma and space - strip these as needed
        }
    }
}

输出:

  

地址= {
      City = Cupertino;
      州= CA;
      Street =" 222 Main Street&#34 ;;
  },范围:{11,30}

奇怪的是,结果的结果词典不包含对星巴克"星巴克"一部分。您可以做的是检查addressComponents是否包含NSTextCheckingNameKey的值。如果没有,请检查匹配范围。如果匹配的范围不是字符串的开头,那么您可以使用该值从字符串的开头提取名称。

答案 1 :(得分:2)

要获得逗号之间的数组,您可以使用:

NSArray *components = [placeResult componentsSeparatedByString:@","];

可能会跟进:

NSMutableArray *trimmedComponents =
           [NSMutableArray arrayWithCapacity:[components count]];

NSCharacterSet *whitespaceCharacterSet = [NSCharacterSet whitespaceCharacterSet];

for(NSString *component in components)
    [trimmedComponents addObject:
             [component stringByTrimmingCharactersInSet:whitespaceCharacterSet]];

从每个单独的组件中删除任何前导或尾随空格。您可以使用例如

来反转转换
NSString *fullAddress = [trimmedComponents componentsJoinedByString:@", "];

那么问题是,鉴于NSString *firstComponent = [trimmedComponents objectAtIndex:0];,您如何猜测它是名称还是街道地址?如果它就像检查前面是否有一个不为零的数字一样简单,那么你就可以这样做:

if([firstComponent integerValue])
{
    /* ... started with a non-zero number ... */

    NSString *trimmedAddress = [[trimmedComponents subArrayWithRange:
      NSMakeRange(1, [trimmedComponents count]-1)] componentsJoinedByString:", "];

    NSLog(@"trimmed address is: %@");
}

虽然这个条件测试也适用于placeResult,你可能想要添加有效性检查以确保在开始假设你可以从第二个创建数组之前至少有两个组件起。