我使用此代碼使用RegEx將HTML字符串轉換爲NSAttributedString。我遇到的唯一問題是嵌套粗體和斜體標籤。 RegEx是正確的方法嗎?將嵌套粗斜體HTML標記轉換爲NSAttributedString
另外我想避免使用HTML解析器,因爲我需要的全部是粗體,斜體和下劃線屬性,並且如果可能,請使用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];
}
}];
}
什麼樣的嵌套標籤導致您問題?你有一個不正確的例子嗎? – Larme
「這是斜體和大膽文本」 - >這不工作,而這個人做 - >「這是斜體和大膽文本」 –
我想你的代碼與你的兩個NSString的測試。它通過了。我所做的最大的不同之處在於,不是改變字體,而是將'NSBackgroundColorAttributeName'設置爲粗體,將'NSForegroundColorAttributeName'設爲斜體。有效。我猜你的字體測試是錯誤的。如果您還沒有應用粗體字體,我不知道它應該如何應用斜體字體。 – Larme