我使用此代码使用RegEx将HTML字符串转换为NSAttributedString。我唯一的问题是嵌套的粗体和斜体标签。 RegEx是正确的方法吗?
另外,我想避免使用HTML解析器,因为我需要的只有Bold,Italic和Underline属性以及StrikeThrough(如果可能)。
有什么建议吗?
- (NSMutableAttributedString *)applyStylesToString:(NSString *)string searchRange:(NSRange)searchRange {
NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:string];
[attributedString addAttribute:NSFontAttributeName value:[StylesConfig regularLargeFont] range:searchRange];
NSDictionary *boldAttributes = @{ NSFontAttributeName : [StylesConfig regularBoldLargeFont] };
NSDictionary *italicAttributes = @{ NSFontAttributeName : [StylesConfig regularItalicLargeFont] };
NSDictionary *underlineAttributes = @{ NSUnderlineStyleAttributeName : @1};
NSDictionary *strikeThroughAttributes = @{ NSStrikethroughStyleAttributeName : @1};
NSDictionary *replacements = @{
@"<b>(.*?)</b>" : boldAttributes,
@"<i>(.*?)</i>" : italicAttributes,
@"<u>(.*?)</u>" : underlineAttributes,
@"<s>(.*?)</s>" : strikeThroughAttributes
};
for (NSString *key in replacements) {
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:key options:0 error:nil];
[regex enumerateMatchesInString:string options:0 range:searchRange usingBlock:^(NSTextCheckingResult *match, NSMatchingFlags flags, BOOL *stop){
NSRange matchRange = [match rangeAtIndex:1];
[attributedString addAttributes:replacements[key] range:matchRange];
if ([key isEqualToString:@"<b>(.*?)</b>"]) {
[self makeBoldItalic:attributedString matchRange:matchRange font:@"SourceSansPro-It"];
} else if ([key isEqualToString:@"<i>(.*?)</i>"]) {
[self makeBoldItalic:attributedString matchRange:matchRange font:@"SourceSansPro-Semibold"];
}
}];
}
[[attributedString mutableString] replaceOccurrencesOfString:@"<b>" withString:@"" options:NSCaseInsensitiveSearch range:NSMakeRange(0, attributedString.length)];
[[attributedString mutableString] replaceOccurrencesOfString:@"</b>" withString:@"" options:NSCaseInsensitiveSearch range:NSMakeRange(0, attributedString.length)];
[[attributedString mutableString] replaceOccurrencesOfString:@"<i>" withString:@"" options:NSCaseInsensitiveSearch range:NSMakeRange(0, attributedString.length)];
[[attributedString mutableString] replaceOccurrencesOfString:@"</i>" withString:@"" options:NSCaseInsensitiveSearch range:NSMakeRange(0, attributedString.length)];
[[attributedString mutableString] replaceOccurrencesOfString:@"<u>" withString:@"" options:NSCaseInsensitiveSearch range:NSMakeRange(0, attributedString.length)];
[[attributedString mutableString] replaceOccurrencesOfString:@"</u>" withString:@"" options:NSCaseInsensitiveSearch range:NSMakeRange(0, attributedString.length)];
[[attributedString mutableString] replaceOccurrencesOfString:@"<s>" withString:@"" options:NSCaseInsensitiveSearch range:NSMakeRange(0, attributedString.length)];
[[attributedString mutableString] replaceOccurrencesOfString:@"</s>" withString:@"" options:NSCaseInsensitiveSearch range:NSMakeRange(0, attributedString.length)];
return attributedString;
}
- (void)makeBoldItalic:(NSMutableAttributedString *)attributedString matchRange:(NSRange)matchRange font:(NSString *)font {
[attributedString enumerateAttribute:NSFontAttributeName inRange:NSMakeRange(0, attributedString.length) options:0 usingBlock:^(id value, NSRange range, BOOL *stop) {
UIFont *oldFont = (UIFont *)value;
if ([oldFont.fontName isEqualToString:font]) {
[attributedString removeAttribute:NSFontAttributeName range:range];
NSDictionary *boldItalicAttributes = @{ NSFontAttributeName : [StylesConfig regularBoldItalicLargeFont] };
[attributedString addAttributes:boldItalicAttributes range:matchRange];
}
}];
}
答案 0 :(得分:5)
事实是Bold和Italic(以及其他属性)是字体的一部分,与下划线不同。 iOS并没有给出一个假的粗体&#34;或者&#34;伪造斜体&#34;就像Photoshop可以做的那样。
所以,我猜您从boldFont
类实用程序中得到了:
italicFont
,boldItalicFont
和boldFont = [StylesConfig regularBoldLargeFont]; //SourceSansPro-Semibold
italicFont = [StylesConfig regularItalicLargeFont];//SourceSansPro-It
boldItalicFont = [StylesConfig regularBoldItalicLargeFont];//SourceSansPro-SemiboldIt (or something like this)
。
symbolicTraits
因此,要更改字体,期望其fontDescriptor
-(void)boldText:(NSMutableAttributedText *)attributeString forRange:(NSRange)range
{
[attributedString enumerateAttribute:NSFontAttributeName inRange:NSMakeRange(0, attributedString.length) options:0 usingBlock:^(id value, NSRange range, BOOL *stop) {
UIFont *currentFont = (UIFont *)value;
if ([[currentFont fontDescriptor] symbolicTraits] & UIFontDescriptorTraitBold)
{
NSLog(@"Font is already bold);
}
else
{
UIFont *newFont = [self boldFontFromFont:currentFont];
[attributedString addAttribute:newFont range:range];
}
}];
}
-(void)italicText:(NSMutableAttributedText *)attributeString forRange:(NSRange)range
{
[attributedString enumerateAttribute:NSFontAttributeName inRange:NSMakeRange(0, attributedString.length) options:0 usingBlock:^(id value, NSRange range, BOOL *stop) {
UIFont *currentFont = (UIFont *)value;
if ([[currentFont fontDescriptor] symbolicTraits] & UIFontDescriptorTraitItalic)
{
NSLog(@"Font is already italic);
}
else
{
UIFont *newFont = [self italicFontFromFont:currentFont];
[attributedString addAttribute:newFont range:range];
}
}];
}
-(UIFont *)boldFontFromFont:(UIFont *)font
{
if ([[currentFont fontDescriptor] symbolicTraits] & UIFontDescriptorTraitItalic)
return boldItalicFont;
else
return boldFont;
}
-(UIFont *)italicFontFromFont:(UIFont *)font
{
if ([[currentFont fontDescriptor] symbolicTraits] & UIFontDescriptorTraitBold)
return boldItalicFont;
else
return italicFont;
}
中的字体包含正确的字体,您可以执行以下操作:
if ([key isEqualToString:@"<b>(.*?)</b>"])
{
[self boldText: attributedString forRange:matchRange];
}
else if ([key isEqualToString:@"<i>(.*?)</i>"])
{
[self italicText: attributedString forRange:matchRange];
}
在您当前的代码中:
symbolicTraits
如果您的字体未通过UIFont
测试,则可能需要查看fontName
fast
并检查其字体是否为粗体,斜体或粗体。
注意:强>
我没有测试代码,我只在这里写,我甚至不知道它是否编译,但那应该给你全部的想法。