3

文字列内のウェブサイトのURLを検出してから、太字にするなどの属性文字列を実行しようとしています。

私の正規表現は次のように定義されています。

static NSRegularExpression *websiteRegularExpression;
static inline NSRegularExpression * WebsiteRegularExpression() {
    if (!websiteRegularExpression) {
        websiteRegularExpression = [[NSRegularExpression alloc] initWithPattern:@"\b(https?|ftp|file)://[-A-Z0-9+&@#/%?=~_|!:,.;]*[A-Z0-9+&@#/%=~_|]" 
                                                                        options:NSRegularExpressionCaseInsensitive 
                                                                          error:nil];
    }

    return websiteRegularExpression;
}

ここに私が列挙するところがあります:

 -(void)setBodyText
    {
        __block NSRegularExpression *regexp = nil;    
        bodyLabel.delegate = self;
        [self.bodyLabel setText:@"http://www.google.com" afterInheritingLabelAttributesAndConfiguringWithBlock:^NSAttributedString *(NSMutableAttributedString *mutableAttributedString) {

            NSRange stringRange = NSMakeRange(0, [mutableAttributedString length]);

            regexp = WebsiteRegularExpression ();
            NSRange nameRange = [regexp rangeOfFirstMatchInString:[mutableAttributedString string] options:0 range:stringRange];
            UIFont *boldSystemFont = [UIFont boldSystemFontOfSize:18.0]; 
            CTFontRef boldFont = CTFontCreateWithName((CFStringRef)boldSystemFont.fontName, boldSystemFont.pointSize, NULL);
            if (boldFont) {
                [mutableAttributedString addAttribute:(NSString *)kCTFontAttributeName value:(id)boldFont range:nameRange];
                CFRelease(boldFont);
            }

            [mutableAttributedString replaceCharactersInRange:nameRange withString:[[[mutableAttributedString string] substringWithRange:nameRange] uppercaseString]];
            return mutableAttributedString;
        }];

        regexp = WebsiteRegularExpression();
        NSRange linkRange = [regexp rangeOfFirstMatchInString:self.bodyLabel.text options:0 range:NSMakeRange(0, [bodyLabel.text length])];
        [self.bodyLabel addLinkToURL:nil withRange:linkRange];
    }

エラーが発生します:

*** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[NSCFString substringWithRange:]: Range or index out of bounds'

どうすれば解決できますか?

4

2 に答える 2

10

substringWithRangeを呼び出す前に、 nameRangeの内容を確認してください。正規表現が一致しない場合、rangeOfFirstMatchInStringの戻り値は次のようになります。

{NSNotFound、0}

NSNotFoundはNSIntegerMaxとして定義されているため、この値がmutableAttributedStringの範囲外である理由を想像できます。

コメントの更新

したがって、substringWithRangeの結果を確認するには:

if (nameRange.location == NSNotFound)
    // didn't match the WebsiteRegularExpression() do something else
于 2011-06-29T03:05:03.173 に答える
4

戻ってきた範囲にrange.location=NSNotFoundがあるかどうかを確認する場所はどこにもありません。マッチの1つが空になり、その範囲を他の目的に使用しようとしています。

于 2011-06-29T03:04:48.807 に答える