在ObjC中获取两个其他字符串之间的字符串

时间:2010-10-23 03:40:47

标签: iphone objective-c

我正在尝试解析一个字符串并在中间获取另一个字符串。

即。

Hello world这是一个字符串

我需要在“world”和“is”(this)之间找到字符串。我环顾四周但还未能弄清楚,主要是因为我是Objective C的新手...任何人都知道如何使用RegEx或不使用?

4 个答案:

答案 0 :(得分:32)

Jacques提供的正则表达式解决方案,以及需要iOS 4.0及更高版本的警告是正确的。使用正则表达式也很慢,如果搜索表达式是已知的字符串常量,那就太过分了。

您可以使用NSString上的方法或名为NSScanner的类来解决问题,这些方法自iPhone OS 2.0以来就已经可用,并且早在Mac OS X 10.0之前就已经可用了。

那么你想要的是NSString这样的新方法吗?

@interface NSString (CWAddition)
- (NSString*) stringBetweenString:(NSString*)start andString:(NSString*)end;
@end

没问题,我们假设我们应该返回nil是不是找不到这样的字符串。

使用NSString的实现非常简单:

@implementation NSString (NSAddition)
- (NSString*) stringBetweenString:(NSString*)start andString:(NSString*)end {
    NSRange startRange = [self rangeOfString:start];
    if (startRange.location != NSNotFound) {
        NSRange targetRange;
        targetRange.location = startRange.location + startRange.length;
        targetRange.length = [self length] - targetRange.location;   
        NSRange endRange = [self rangeOfString:end options:0 range:targetRange];
        if (endRange.location != NSNotFound) {
           targetRange.length = endRange.location - targetRange.location;
           return [self substringWithRange:targetRange];
        }
    }
    return nil;
}
@end

或者您可以使用NSScanner类来执行实现:

@implementation NSString (NSAddition)
- (NSString*) stringBetweenString:(NSString*)start andString:(NSString*)end {
    NSScanner* scanner = [NSScanner scannerWithString:self];
    [scanner setCharactersToBeSkipped:nil];
    [scanner scanUpToString:start intoString:NULL];
    if ([scanner scanString:start intoString:NULL]) {
        NSString* result = nil;
        if ([scanner scanUpToString:end intoString:&result]) {
            return result;
        }
    }
    return nil;
}
@end

答案 1 :(得分:12)

只是对PeyloW的答案的一个简单修改,它返回开始和结束字符串中的所有字符串:

-(NSMutableArray*)stringsBetweenString:(NSString*)start andString:(NSString*)end
{

  NSMutableArray* strings = [NSMutableArray arrayWithCapacity:0];

  NSRange startRange = [self rangeOfString:start];

  for( ;; )
  {

    if (startRange.location != NSNotFound)
    {

      NSRange targetRange;

      targetRange.location = startRange.location + startRange.length;
      targetRange.length = [self length] - targetRange.location;   

      NSRange endRange = [self rangeOfString:end options:0 range:targetRange];

      if (endRange.location != NSNotFound)
      {

        targetRange.length = endRange.location - targetRange.location;
        [strings addObject:[self substringWithRange:targetRange]];

        NSRange restOfString;

        restOfString.location = endRange.location + endRange.length;
        restOfString.length = [self length] - restOfString.location;

        startRange = [self rangeOfString:start options:0 range:restOfString];

      }
      else
      {
        break;
      }

    }
    else
    {
      break;
    }

  }

  return strings;

}

答案 2 :(得分:3)

请参阅ICU user guide on regular expressions

如果你知道只有一个结果:

NSRegularExpression *regex = [NSRegularExpression
    regularExpressionWithPattern:@"\bworld\s+(.+)\s+is\b" options:0 error:NULL]

NSTextCheckingResult *result = [regex firstMatchInString:string
    options:0 range:NSMakeRange(0, [string length]];

// Gets the string inside the first set of parentheses in the regex
NSString *inside = [string substringWithRange:[result rangeAtIndex:1]];

\ b确保在世界之前和之后有一个单词边界(因此“hello world这不是一个字符串”将不匹配)。 \ s在世界之后和之前的任何空格都会吞噬。 。+?找到你要找的东西,用?使它非贪婪,以便“hello world这是一个字符串hello world这是一个字符串”并没有给你“这个字符串你好世界”。

我会告诉你如何处理多个匹配。 NSRegularExpression文档可以帮助您。

如果你想确保匹配不跨越句子边界,你可以做(​​[^。] +?)而不是(。+?),或者你可以在你的字符串上使用enumerateSubstringsInRange:options:usingBlock:并在选项中传递NSStringEnumerationBySentences。

这些东西都需要4.0+。如果您想支持3.0+,请查看RegexKitLite。

答案 3 :(得分:1)

如果它恰好是由空格分隔的字符串,则可以使用以下代码:

[string componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]

OR

NSMutableArray *parts = [NSMutableArray arrayWithCapacity:1];

NSScanner *scanner = [NSScanner scannerWithString:string];
NSString *token;
while ([scanner scanUpToCharactersFromSet:[NSCharacterSet whitespaceCharacterSet]] intoString:&token]) {
    [parts addObject:token];
}