NSScanner 的显着行为

发布于 2024-12-23 18:00:51 字数 1359 浏览 2 评论 0原文

我在 NSTextView 中有以下字符串:

荷鲁斯为父亲奥西里斯报仇

为此分配了两个标签,荷鲁斯奥西里斯。我使用 NSScanner 扫描字符串中的两个标签,并在找到时用黄色背景突出显示它们。

代码是:

for (Tag *aTag in tags) {
    NSString *aTagName = [aTag name];
    NSUInteger strLength = [aTagName length];
    NSScanner *aScanner = [[NSScanner alloc] initWithString: aString];
    [aScanner setCaseSensitive: YES];
    [aScanner setScanLocation: 0];
    BOOL result = [aScanner scanUpToString: aTagName intoString: nil];
    while (![aScanner isAtEnd]) {
        NSUInteger position = [aScanner scanLocation];
        if (result) {
            NSRange aRange = NSMakeRange(position, strLength);
            [storage removeAttribute: NSBackgroundColorAttributeName range: aRange];
            if (onOrOff) {
                [storage addAttribute: NSBackgroundColorAttributeName value: aColor range: aRange];
            }
            position = position + [aTagName length];
            [aScanner setScanLocation: position];
        }
        [aScanner scanUpToString: aTagName intoString: nil];
    }
}

当第一个标签(在上面的示例中是 Horus)位于扫描字符串的最开头(位置 = 0)时,此操作会失败。找不到标签,代码一直循环。

但是,当我将字符串替换为:

十年后荷鲁斯为父亲奥西里斯报仇

……一切顺利,我的两个标签都被发现(如预期)并很好地突出显示。

我是否遗漏了什么或者这是 NSScanner 中的错误?

I have the following string in an NSTextView:

Horus avenged his father Osiris

There are two tags assigned to this, Horus and Osiris. I use NSScanner to scan the string for both tags and highlight them with a yellow background when found.

The code is:

for (Tag *aTag in tags) {
    NSString *aTagName = [aTag name];
    NSUInteger strLength = [aTagName length];
    NSScanner *aScanner = [[NSScanner alloc] initWithString: aString];
    [aScanner setCaseSensitive: YES];
    [aScanner setScanLocation: 0];
    BOOL result = [aScanner scanUpToString: aTagName intoString: nil];
    while (![aScanner isAtEnd]) {
        NSUInteger position = [aScanner scanLocation];
        if (result) {
            NSRange aRange = NSMakeRange(position, strLength);
            [storage removeAttribute: NSBackgroundColorAttributeName range: aRange];
            if (onOrOff) {
                [storage addAttribute: NSBackgroundColorAttributeName value: aColor range: aRange];
            }
            position = position + [aTagName length];
            [aScanner setScanLocation: position];
        }
        [aScanner scanUpToString: aTagName intoString: nil];
    }
}

This fails when the frist tag (in the above example it's Horus) is located at the very beginning (location = 0) of the scanned string. The tag is not found and the code keeps looping.

However, when I replace the string with:

After 10 years Horus avenged his father Osiris

... it all works and both my tags are found (as expected) and nicely highlighted.

Am I missing something or is this a bug in NSScanner?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

悲欢浪云 2024-12-30 18:00:51

请参阅文档

- (BOOL)scanUpToString:(NSString *)stopString intoString:(NSString **)stringValue

如果 stopString 是接收器中的第一个字符串,则该方法返回 NO 并且 stringValue 不会更改。

扫描器已找到该字符串,但返回“否”,因为它尚未扫描任何字符来执行此操作。然后,您的代码不会增加 position 变量,因为该部分位于 if (result) 块内。

我认为删除 if 语句应该可以解决问题。如果扫描器没有找到 stopString,则 while 条件将失败,并且代码根本不会进入循环。

See the docs for

- (BOOL)scanUpToString:(NSString *)stopString intoString:(NSString **)stringValue

If stopString is the first string in the receiver, then the method returns NO and stringValue is not changed.

The scanner has found the string, but returned NO, because it has not scanned through any characters to do so. Your code then doesn't increase the position variable, because that part is within the if (result) block.

I think removing the if statement should fix the problem. If the scanner didn't find the stopString, the while condition will fail and the code won't get into the loop at all.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文