用NSAttributedString

时间:2018-09-06 14:10:01

标签: ios objective-c regex nsstring

我有一个Emoji个实体的列表,每个实体都有一个属性codes,我想检查字符串("]:-)")是否包含其中的任何一个,然后将Smile替换为图片。

for (Emoji *emoji in self.emojis) {
    for (NSString *code in emoji.codes) {
        NSString *pattern = [NSRegularExpression escapedPatternForString:code];
        NSRegularExpression *regex = [[NSRegularExpression alloc] initWithPattern:pattern options:0 error:nil];

        NSArray *matches = [regex matchesInString:[sourceString string] options:0 range:NSMakeRange(0, [sourceString length])];

        [matches enumerateObjectsWithOptions:NSEnumerationReverse usingBlock:^(NSTextCheckingResult * _Nonnull aResult, NSUInteger idx, BOOL * _Nonnull stop) {
            NSTextAttachment *attachment = [[NSTextAttachment alloc] init];
            [attachment setImage:[UIImage imageNamed:emoji.image]];

            NSAttributedString *replacement = [NSAttributedString attributedStringWithAttachment:attachment];
            [sourceString replaceCharactersInRange:[aResult range] withAttributedString:replacement];
        }];
    }
}

问题是代码为]:-)的笑容包含:-),而我的方法将其替换为next:括号 ] + [image] {1}},这是因为:-)在列表中排在第一位。

如何检查确切的字符串?

我尝试过: :-)]:-/)\\b]:-/)\\b

也许有更好的解决方案可以使它正常工作。

1 个答案:

答案 0 :(得分:1)

如果我正确理解了您当前的结构:

@interface Emoji : NSObject
@property (nonatomic, strong) NSString *image; //I'd expect a UIImage there and not an image name
@property (nonatomic, strong) NSArray *codes;
@end

一个可能的解决方案是使用几个值:imageName / code

@interface Emoji : NSObject
@property (nonatomic, strong) NSString *image; //I'd expect a UIImage there and not an image name
@property (nonatomic, strong) NSString *code;
@end

self.emojis将具有许多Emoji对象,这些对象对于不同的代码可能具有相同的图像名称,但是这样做的好处是这个小技巧:
以“较小”的表情符号结尾的方式对self.emojis进行排序。因此,您将首先仅替换“长”的和较小的。

self.emojis = [arrayOfSingleEmojis sortedArrayUsingComparator:^NSComparisonResult(Emoji * _Nonnull emoji1, Emoji * _Nonnull emoji2) {
    NSUInteger length1 = [[emoji1 code] length];
    NSUInteger length2 = [[emoji2 code] length];
    return [@(length2) compare:@(length1)]; //Or reverse length1 & length2, I never know, I always have to test, but I think it's the correct one
}];

因此,在您当前的情况下:]:-)将在:-)之前被替换,因此您应该使用<imageFor:">:-)"]而不是]<imageFor:":-)>