NSString - rangeOfString方法,忽略先前出现的字符串

时间:2013-03-31 11:34:24

标签: objective-c nsstring

从文档中,我意识到每个rangeOfString方法&它的变体在字符串中找到第一个匹配项。所以,如果我有一个“我可以拥有或不拥有”的字符串,它将永远不会捕获“我”的第二个实例。我可以使用NSBackwardsSearch运算符,但它会找到最后一个但不是第一个。

我要做的是在视图中使用步进器按顺序为句子中的每个单词加下划线。但是当它找到之前遇到的相同单词时会出现问题,因为它会强调该单词的第一次出现而不是当前位置所在的第二次出现。

有关如何使用rangeOfString忽略先前出现的字符串的任何建议?或者我可以用另一种方法来实现这个目标吗?

-Yohannes

3 个答案:

答案 0 :(得分:3)

使用-rangeOfString:options:range:...方法之一,在您已找到的范围之后传递范围。

答案 1 :(得分:1)

NSString *str = @"I can have I or not";

NSUInteger count = 0, length = [str length];
NSRange range = NSMakeRange(0, length);
while(range.location != NSNotFound)
{
    range = [str rangeOfString: @"I" options:0 range:range];
    if(range.location != NSNotFound)
    {
        range = NSMakeRange(range.location + range.length, length - (range.location + range.length));
        NSLog(@"found %@",NSStringFromRange(range));
        count++; 
    }
}

答案 2 :(得分:0)

请注意,如果您只使用子字符串,那么您还将匹配作为其他单词一部分的子字符串,例如第二段中“出现”中的“是”。根据您的描述而不是您想要的,但我可能误解了它。

Core Foundation提供CFStringTokenizer,可帮助您在不同的区域设置中执行这些操作。

以下代码未以任何方式进行优化:

NSString *para = @"What I am trying to do is using a Stepper in my View to underline every word in a sentence sequentially. But the problem arises when it finds the same word it has encountered before for it will underline the 1st occurrence of that word instead of the 2nd occurrence where the current location is.";

NSString *searchedWord = @"is";

NSUInteger selectedOccurrence = 2;  // From your stepper, zero-based.
NSUInteger counter            = NSNotFound;
NSRange    selectedRange      = NSMakeRange(NSNotFound, 0);

CFStringTokenizerRef tokenizer = CFStringTokenizerCreate (NULL,(CFStringRef)para,CFRangeMake(0, para.length),kCFStringTokenizerUnitWord,NULL);

CFStringTokenizerTokenType tokenType;


while ( (tokenType = CFStringTokenizerAdvanceToNextToken(tokenizer)) != kCFStringTokenizerTokenNone ) {

    CFRange tokenRange = CFStringTokenizerGetCurrentTokenRange(tokenizer);

    NSString *token = (__bridge_transfer NSString*)CFStringCreateWithSubstring(kCFAllocatorDefault, (CFStringRef)para, tokenRange);

    if ( [token compare:searchedWord options:NSCaseInsensitiveSearch] == NSOrderedSame ) {

        // An occurrence of the word is found!

        counter = counter == NSNotFound ? 0 : counter + 1;

        if ( counter == selectedOccurrence ) {

            // We found the occurrence we were looking for

            selectedRange = NSMakeRange(tokenRange.location, tokenRange.length);

            break;
        }
    }
};

// If selectedRange is different from the initial {NSNotFound,0} then we found something
if ( ! NSEqualRanges(selectedRange, NSMakeRange(NSNotFound, 0)) ) {
    // Highlight your word found at selectedRange
    NSLog(@"Found at %@", NSStringFromRange(selectedRange));
}
else {
    // Not found, clean up
    NSLog(@"An occurence number %ld not found", selectedOccurrence);
}