我的目标是在Parse.com中存储属性字符串的信息。我决定为我的图像提供一个索引文本的编码,通过用相应的图像替换大括号中的任何字符串{X}
来工作。例如:
Picture of 2 colorless mana: {X}
应该生成一个属性字符串,其中{X}
被图像替换。这就是我尝试过的:
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];
目前这种方法存在两个问题:
答案 0 :(得分:7)
两个问题:
不替换大括号。那是因为你正在使用断言,这些断言不算作比赛的一部分。您使用模式进行的匹配仅包含大括号内的内容。请改用此模式:
\{([^}]+)\}
那是:匹配一个大括号,然后是一个或多个未在捕获组中关闭大括号的东西,后跟一个右大括号。整个比赛现在包括括号。
这引入了另一个问题 - 你使用封闭的位来挑选替换图像。解决此问题的小改动:内部捕获组现在拥有该信息,而不是整个组。捕获组的长度告诉您所需子串的范围。
NSUInteger lengthOfManaName = [result rangeAtIndex:1].length;
NSString manaName = [match substringWithRange:(NSRange){1, lengthOfManaName}];
imageAttachment.image = [UIImage imageNamed:[NSString stringWithFormat:@"Mana%@.png", manaName]];
第二个问题:字符串的长度在变化。 Just enumerate backwards:
for (NSTextCheckingResult *result in [matches reverseObjectEnumerator])
{
//...
}
现在更改为字符串末尾的范围不会影响早期范围。