0

从文档中,我意识到每个 rangeOfString 方法及其变体都会在字符串中找到第一次出现。因此,如果我有一串“我可以拥有或不拥有”,它将永远不会捕获“I”的第二个实例。我可以使用 NSBackwardsSearch 运算符,但它会找到最后一个但不是第一个。

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

关于如何使用 rangeOfString 忽略先前出现的字符串的任何建议?还是有另一种方法可以做到这一点?

-约哈内斯

4

3 回答 3

3

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

于 2013-03-31T11:42:13.770 回答
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++; 
    }
}
于 2013-03-31T12:47:06.613 回答
0

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

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);
}
于 2013-03-31T14:10:16.340 回答