用Objective-C中的图像替换属性字符串中的正则表达式匹配 [英] Replace regex matches in attributed string with image in Objective-C

查看:49
本文介绍了用Objective-C中的图像替换属性字符串中的正则表达式匹配的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的目标是在 Parse.com 中存储属性字符串的信息.我决定为我的图像提出一种属性文本编码,通过用相应的图像替换大括号中的任何字符串 {X} 来工作.例如:

My goal is to store the information for an attributed string in Parse.com. I decided to come up with an encoding for attributed text for my images that works by replacing any string {X} in braces with the corresponding image. For example:

Picture of 2 colorless mana: {X}

应该生成一个属性字符串,其中 {X} 被图像替换.这是我试过的:

Should produce an attributed string where {X} is replaced by an image. This is what I've tried:

NSString *formattedText = @"This will cost {2}{PW}{PW} to cast.";
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"(?<=\\{)[^}]+(?=\\})" options:NSRegularExpressionAnchorsMatchLines
                                                                         error:nil];
NSArray *matches = [regex matchesInString:formattedText
                                  options:kNilOptions
                                    range:NSMakeRange(0, formattedText.length)];
NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:formattedText];
for (NSTextCheckingResult *result in matches)
{
    NSString *match = [formattedText substringWithRange:result.range];
    NSTextAttachment *imageAttachment = [NSTextAttachment new];
    imageAttachment.image = [UIImage imageNamed:[NSString stringWithFormat:@"Mana%@.png", match]];
    NSAttributedString *replacementForTemplate = [NSAttributedString attributedStringWithAttachment:imageAttachment];
    [attributedString replaceCharactersInRange:result.range
                          withAttributedString:replacementForTemplate];
}
[_textView setAttributedText:attributedString];

目前这种方法有两个问题:

There are two problems with this approach currently:

  • 不会替换大括号,只会替换其中的文本.
  • 每个匹配的范围都在变化,因为字符串本身在变化,并且随着原始文本长度 > 1 的每次替换,它的变化幅度更大.这是它的样子:

推荐答案

两个问题:

大括号不会被替换.那是因为您使用了断言,这些断言不算作匹配的一部分.您与模式进行的匹配仅包含大括号内的内容.请改用此模式:

Braces aren't replaced. That's because you're using assertions, which aren't counted as part of the match. The match you're making with your pattern only contains the stuff inside the braces. Use this pattern instead:

\{([^}]+)\}

即:匹配一个大括号,后跟一个或多个不是捕获组中的右大括号的内容,然后是一个右大括号.整个比赛现在包括大括号.

That's: match a brace, followed by one or more things that aren't closing braces in a capture group, followed by a closing brace. The whole match includes the braces now.

不过,这引入了另一个问题——您正在使用封闭的位来选择替换图像.解决这个问题的小改动:内部捕获组现在保存该信息,而不是整个组.捕获组的长度告诉您需要的子字符串的范围.

That introduces another problem, though -- you're using the enclosed bits to pick the replacement image. Small change to fix this: the internal capture group holds that information, now, rather than the whole group. The capture group's length tells you the range of the substring you need.

NSUInteger lengthOfManaName = [result rangeAtIndex:1].length;
NSString manaName = [match substringWithRange:(NSRange){1, lengthOfManaName}];
imageAttachment.image = [UIImage imageNamed:[NSString stringWithFormat:@"Mana%@.png", manaName]];

第二个问题:字符串的长度正在改变.只需向后枚举:

Second problem: length of string is changing. Just enumerate backwards:

for (NSTextCheckingResult *result in [matches reverseObjectEnumerator])
{
    //...
}

对字符串末尾范围的更改现在不会影响之前的范围.

Changes to ranges towards the end of the string now won't affect earlier ranges.

这篇关于用Objective-C中的图像替换属性字符串中的正则表达式匹配的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆