【发布时间】:2010-10-23 03:40:46
【问题描述】:
我正在尝试解析一个字符串并在中间获取另一个字符串。
即。
Hello world 这是一个字符串
我需要找到“world”和“is”(this)之间的字符串。我环顾四周,但还没有弄明白,主要是因为我是 Objective C 的新手......有人知道如何做到这一点,无论是否使用 RegEx?
【问题讨论】:
标签: iphone objective-c
我正在尝试解析一个字符串并在中间获取另一个字符串。
即。
Hello world 这是一个字符串
我需要找到“world”和“is”(this)之间的字符串。我环顾四周,但还没有弄明白,主要是因为我是 Objective C 的新手......有人知道如何做到这一点,无论是否使用 RegEx?
【问题讨论】:
标签: iphone objective-c
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
【讨论】:
只是对 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;
}
【讨论】:
请参阅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 确保在 world 之前和 is 之后有一个单词边界(因此“hello world 这不是字符串”不匹配)。 \s 吞噬了世界之后和之前的任何空白。 .+?使用 ? 查找您要查找的内容使其不贪婪,这样“hello world 这是一个字符串 hello world 这是一个字符串”不会给你“this a string hello world this”。
我将由您来决定如何处理多个匹配项。 NSRegularExpression 文档应该可以帮助您。
如果您想确保匹配不会跨越句子边界,您可以使用 ([^.]+?) 而不是 (.+?),或者您可以在字符串上使用 enumerateSubstringsInRange:options:usingBlock:并在选项中传递 NSStringEnumerationBySentences。
这些东西都需要4.0+。如果您想支持 3.0+,请查看 RegexKitLite。
【讨论】:
如果它恰好是由空格分隔的字符串,您可以使用以下代码:要么
[string componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]
或
NSMutableArray *parts = [NSMutableArray arrayWithCapacity:1];
NSScanner *scanner = [NSScanner scannerWithString:string];
NSString *token;
while ([scanner scanUpToCharactersFromSet:[NSCharacterSet whitespaceCharacterSet]] intoString:&token]) {
[parts addObject:token];
}
【讨论】: