Получить строку между двумя другими строками в ObjC
Я пытаюсь разобрать строку и получить другую строку посередине.
т.
Привет, мир, это строка
Мне нужно найти строку между "world" и "is" (это). Я огляделся, но еще не смог понять, в основном потому, что я новичок в Objective C... У кого-нибудь есть идея, как это сделать, с RegEx или без?
Ответы
Ответ 1
Решение регулярных выражений, которое Жак дает, и оговорка о требованиях к 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
Ответ 2
Просто простая модификация ответа 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;
}
Ответ 3
См. Руководство пользователя ICU для регулярных выражений.
Если вы знаете, что будет только один результат:
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 гарантирует, что граница слова перед миром и после (так что "привет мир это не строка" не будет соответствовать).\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\W \. +? находит то, что вы ищете, с помощью? делая его неживым, так что "hello world this is the world hello world this is a string" не дает вам "эту строку hello world this".
Я оставлю это для вас, чтобы выяснить, как обрабатывать несколько совпадений. Документация NSRegularExpression должна помочь вам.
Если вы хотите убедиться, что совпадение не пересекает границы предложения, вы можете сделать ([^.] +?) вместо (. +?), или вы можете использовать enumerateSubstringsInRange: options: usingBlock: на вашей строке и передайте NSStringEnumerationBySentences в параметрах.
Все это требует 4.0+. Если вы хотите поддерживать 3.0+, посмотрите в RegexKitLite.
Ответ 4
Если это просто строки, разделенные пробелами, вы можете использовать следующий код: Либо
[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];
}