使用正则表达式模式作为字符串分隔符时,如何使用NSRegularExpression的结果

时间:2014-08-22 07:09:46

标签: ios objective-c regex nsregularexpression

我使用NSRegularExpression的简单模式在字符串中分隔内容

  

(\ S)+(和|或)(\ S)+

所以,当我使用matchesInString时,它不是我感兴趣的匹配项,而是其他内容

以下是我正在使用的代码。迭代匹配,然后使用索引和长度来提取内容。

问题:我只是想知道我是否遗漏了api中的某些内容以获取其他内容?或者,下面的方法一般都可以吗?

- (NSArray*)separateText:(NSString*)text
{
    NSString* regExPattern = @"(\\s)+(and|or)(\\s)+";
    NSError* error = NULL;
    NSRegularExpression* regex = [NSRegularExpression regularExpressionWithPattern:regExPattern
                                                                           options:NSRegularExpressionCaseInsensitive
                                                                             error:&error];

    NSArray* matches = [regex matchesInString:text options:0 range:NSMakeRange(0, text.length)];

    if (matches.count == 0) {
        return @[text];
    }

    NSInteger itemStartIndex = 0;
    NSMutableArray* result = [NSMutableArray new];

    for (NSTextCheckingResult* match in matches) {
        NSRange matchRange = [match range];

        if (!matchRange.location == 0) {
            NSInteger matchStartIndex = matchRange.location;
            NSInteger length = matchStartIndex - itemStartIndex;
            NSString* item = [text substringWithRange:NSMakeRange(itemStartIndex, length)];

            if (item.length != 0) {
                [result addObject:item];
            }
        }

        itemStartIndex = NSMaxRange(matchRange);
    }

    if (itemStartIndex != text.length) {
        NSInteger length = text.length - itemStartIndex;
        NSString* item = [text substringWithRange:NSMakeRange(itemStartIndex, length)];
        [result addObject:item];
    }

    return result;
}

2 个答案:

答案 0 :(得分:1)

您可以使用模板字符串替换正则表达式的所有匹配项(例如","或","等),然后根据新的分隔符分隔字符串组件。

 NSString *stringToBeMatched = @"Your string to be matched";
 NSString *regExPattern = @"(\\s)+(and|or)(\\s)+";
 NSError *error = nil;
 NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:regExPattern
                                                                               options:NSRegularExpressionCaseInsensitive
                                                                                 error:&error];

        if (error) {
            // handle error
        }

        NSString *replacementString = [regex stringByReplacingMatchesInString:stringToBeMatched
                                                                      options:0
                                                                        range:NSMakeRange(0, stringToBeMatched.length)
                                                                 withTemplate:@","];

        NSArray *otherItemsInString = [replacementString componentsSeparatedByString:@","];

答案 1 :(得分:1)

您可以使用括号捕获and|or前的字符串,并使用rangeAtIndex将其添加到数组中。

NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"(.+?)(\\s+(and|or)\\W+|\\s*$)" options:NSRegularExpressionCaseInsensitive error:&error];

NSMutableArray *phrases = [NSMutableArray array];
[regex enumerateMatchesInString:string options:0 range:NSMakeRange(0, [string length]) usingBlock:^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop) {
    NSRange range = [result rangeAtIndex:1];
    [phrases addObject:[string substringWithRange:range]];
}];

关于我的正则表达式的一些小问题:

  1. 我添加了|\\s*$构造来捕获最终and|or之后的最后一个字符串。如果你不想那样,你就可以消除它。

  2. 我用\\s+(非单词字符)替换了第二个\\W+(空格),以防您遇到类似and|or后跟逗号或其他内容的内容。如果逗号是您唯一关心的非单词字符,您也可以明确查看,?\\s+。这取决于您正在解决的具体业务问题。

    您可能也希望将第一个\\s+替换为\\W+

  3. 如果您的字符串包含换行符,则在实例化NSRegularExpressionDotMatchesLineSeparators时可能需要使用NSRegularExpression选项。