1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
//
// GMHighlightStrGenerator.m
// GMKit
//
// Created by wangyang on 2020/4/14.
//
#import "GMHighlightStrGenerator.h"
@implementation GMHighlightStrGenerator
- (void)debugConfig {
NSAssert(self.hightlightColor, @"GMHighlightStrGenerator.hightlightColor不可以为空");
NSAssert(self.normalColor, @"GMHighlightStrGenerator.normalColor不可以为空");
NSAssert(self.hightlightFont, @"GMHighlightStrGenerator.hightlightFont不可以为空");
NSAssert(self.font, @"GMHighlightStrGenerator.font不可以为空");
}
- (nullable NSMutableAttributedString *)generateWithString:(NSString *)str {
if (str.length == 0) {
return nil;
}
#ifdef DEBUG
[self debugConfig];
#endif
NSMutableAttributedString *resultAttrString = [self parseHighlight:str];
// 创建一个NSMutableParagraphStyle,以便稍后复用
NSMutableParagraphStyle *style = [[NSMutableParagraphStyle alloc] init];
style.lineSpacing = _lineHeight;
style.lineBreakMode = NSLineBreakByTruncatingTail;
style.alignment = _aligment;
if (resultAttrString.length > 0) {
// 如果有高亮,resultAttrString不为空,那只加一个NSParagraphStyleAttributeName属性
[resultAttrString addAttribute:NSParagraphStyleAttributeName value:style range:NSMakeRange(0, resultAttrString.length)];
} else if (resultAttrString.length == 0) {
// 如果没有走到正则里面,说明没有需要高亮的内容,设置普通颜色就好
NSAttributedString *subString = [[NSAttributedString alloc] initWithString:str attributes:@{NSFontAttributeName : self.font, NSForegroundColorAttributeName:_normalColor, NSParagraphStyleAttributeName:style}];
[resultAttrString appendAttributedString:subString];
}
return resultAttrString;
}
/// 解析出<ems>xxx</ems>,并将对应的 xxx 文本设置为高亮颜色
- (NSMutableAttributedString *)parseHighlight:(NSString *)str {
NSError *error;
NSRegularExpression *expression = [NSRegularExpression regularExpressionWithPattern:@"([\\w\\W]*)<ems>([\\w\\W]+)<\\/ems>([\\w\\W]*)" options:0 error:&error];
if (error) {
return nil;
}
NSMutableAttributedString *attString = [[NSMutableAttributedString alloc] init];
[expression enumerateMatchesInString:str options:0 range:NSMakeRange(0, str.length) usingBlock:^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop) {
// 根据NSTextCheckingResult的rangeAtIndex方法文档
// result至少会有一个range,这个range是匹配它自身全部的,所以正则匹配的其它range是从1开始的
// <ems></ems>将string分隔为如下三个部分
// string1:对应<ems>标签前的文本
// string2:对应标签中的高亮文本
// string3:对应</ems>标签后的文本
NSString *string1 = [str substringWithRange:[result rangeAtIndex:1]];
NSAttributedString *attrString1 = [self parseHighlight:string1];
if (attrString1.length > 0) {
[attString appendAttributedString:attrString1];
}else{
NSAttributedString *subString = [[NSAttributedString alloc] initWithString:string1 attributes:@{NSFontAttributeName : _font, NSForegroundColorAttributeName:_normalColor}];
[attString appendAttributedString:subString];
}
NSString *string2 = [str substringWithRange:[result rangeAtIndex:2]];
NSAttributedString *attrString2 = [self parseHighlight:string2];
if (attrString2.length > 0) {
[attString appendAttributedString:attrString2];
}else{
NSAttributedString *subString = [[NSAttributedString alloc] initWithString:string2 attributes:@{NSFontAttributeName : _hightlightFont, NSForegroundColorAttributeName:_hightlightColor}];
[attString appendAttributedString:subString];
}
NSString *string3 = [str substringWithRange:[result rangeAtIndex:3]];
NSAttributedString *attrString3 = [self parseHighlight:string3];
if (attrString3.length > 0) {
[attString appendAttributedString:attrString3];
}else{
NSAttributedString *subString = [[NSAttributedString alloc] initWithString:string3 attributes:@{NSFontAttributeName : _font, NSForegroundColorAttributeName:_normalColor}];
[attString appendAttributedString:subString];
}
}];
return attString;
}
@end