我最近一直在为一个个人项目开发一个易于使用的语法高亮系统。到目前为止,通过查找特定字符串的范围并在NSTextView中突出显示该范围,我可以正常工作。一切都有效,直到您尝试两次输入突出显示的单词,这会导致下面显示的错误:
<div class="container">
<div> <!-- This <div> would not get highlighted -->
Hello World
</div>
</div> <!-- this </div> would not get highlighted -->
我相信这是因为我只使用rangeOfString方法首次出现NSString,因此只突出显示第一个突出显示的项目。
很抱歉很长的解释!无论如何,我想知道是否有一个rangeOfString方法或类似的东西,可以在另一个NSString中为NSString的每次出现提供NSRanges的NSArray。下面是我目前使用的代码行:
NSString *textViewString = [textView string];
NSString *textToHighlight = @"<div>";
NSRange area;
area.location = 0;
area.length = [textViewString length];
NSRange range = [textViewString rangeOfString: textToHighlight
options: NSCaseInsensitiveSearch
range: area];
我想要的是这样的:
NSString *textViewString = [textView string];
NSString *textToHighlight = @"<div>";
NSRange area;
area.location = 0;
area.length = [textViewString length];
NSArray *ranges = [textViewString rangesOfString: textToHighlight
options: NSCaseInsensitiveSearch
range: area];
int i;
int total = [ranges count];
for (i = 0; i < total; i++) {
NSRange occurrence = [ranges objectAtIndex: i];
// Apply color highlighting here
}
如果这是不可能的,有人可以指出我正确的方向或建议另一种方法进行语法高亮?谢谢!
答案 0 :(得分:3)
没有这样的方法。您可以使用rangeOfSubstring:options:range:
来获取每个匹配,并随时缩小范围:在每次匹配后,您将搜索范围的位置更改为匹配范围(位置+长度)之后的字符,并缩小搜索范围差异的长度。
在现代的基于块的世界中,编写实现上述内容的an “enumerate substrings that match…” method并不难。这是看起来像:
- (NSUInteger) enumerateSubstringsMatchingString_PRH:(NSString *)stringToFind
options:(NSStringCompareOptions)mask
usingBlock:(void (^)(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop))block
{
NSUInteger count = 0;
NSUInteger selfLength = self.length;
NSRange searchRange = { 0, selfLength };
NSRange foundRange;
BOOL stop = NO;
while (( ! stop ) && (foundRange = [self rangeOfString:stringToFind options:mask range:searchRange]).location != NSNotFound) {
++count;
if (block != NULL) {
@autoreleasepool {
NSString *substring = [self substringWithRange:foundRange];
block(substring, foundRange, /*TODO include terminators and separators in enclosingRange as described in enumerateSubstringsWithOptions:: docs*/ foundRange, &stop);
}
}
searchRange.location = NSMaxRange(foundRange);
if (searchRange.location >= self.length)
break;
searchRange.length = selfLength - searchRange.location;
}
return count;
}
上面链接的Gist提供了一些明显的测试用例。
答案 1 :(得分:1)
NSRange不是对象,因此您需要将其放在一个对象中。查看NSValue
+valueWithRange:
类方法。