好久没有认真的写博客及分享了,终于周五了,也五一了,。。。。。。。 来吧,继续我们的技术分享,这里只是为了探究技术实现,绕过了正则表达式来识别的无助及懵逼,而是自己写算法进行识别。供中等开发同学进行技术研究。
先上图看看识别效果:
识别过程中使用的类:
@interface CTLinkData : NSObject
@property (strong, nonatomic) NSString * title;
@property (strong, nonatomic) NSString * url;
@property (assign, nonatomic) NSRange range;
@property (assign, nonatomic) CGRect rect;
@end
识别成功后,自己给富文本添加颜色、下划线,点击等事情就可以了。CTLinkData会记录识别的起始及终点位置。正常使用即可。
+ (NSMutableArray <CTLinkData*>*)matchWebLink:(NSString *)targetText
{
NSMutableArray <NSValue*>*elist = (NSMutableArray *)[targetText mutableRangeOfString:@"(www|http|https|ftp)"];
NSArray *prefixTextList = [NSArray arrayWithObjects:@".com",@".cn",@".com.cn",@".edu",@".gov",@".mil",@".net",@".org",@".biz",@".info",@".name",@".museum",@".us",@".ca|uk",@".html",@".htm",@".jsp html",@".php",@".asp",@".phtml", nil];
NSMutableArray *linkArr = [NSMutableArray arrayWithCapacity:0];
[elist enumerateObjectsUsingBlock:^(NSValue * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
NSRange rg = obj.rangeValue;
NSString *stext = [targetText substringFromIndex:rg.location];
NSInteger lth = stext.length;
NSInteger pdex = 1;
while (pdex < lth-1)
{
__block BOOL fexFlag = NO;
if (rg.length + pdex < stext.length)
{
NSString *pex = [stext substringWithRange:NSMakeRange(rg.length, pdex)];
[prefixTextList enumerateObjectsUsingBlock:^(NSString *obj, NSUInteger idx, BOOL * _Nonnull stop) {
NSString *ct = nil;
if (stext.length>pdex+1)
{
ct = [stext substringWithRange:NSMakeRange(rg.length+pdex, 1)];
}
BOOL nextCt = [ct isEqualToString:@"/"] || [ct isEqualToString:@"."];
if ([pex containsString:obj] && [pex rangeOfString:obj].location == pex.length-obj.length && !nextCt)
{
fexFlag = YES;
*stop = YES;
}
}];
}
NSString *ct = [stext substringWithRange:NSMakeRange(pdex+rg.length, 1)];
if (rg.location+stext.length == targetText.length && !([stext containsString:@"\r"] || [stext containsString:@"\n"] || [stext containsString:@" "]))
{
fexFlag = YES;
pdex = stext.length - rg.length - 1;
}
if ([ct isEqualToString:@" "] || [ct isEqualToString:@"\n"] || fexFlag)
{
rg.length = rg.length+pdex+1;
NSString *targetStr = [targetText substringWithRange:rg];
CTLinkData *linkData = [[CTLinkData alloc] init];
linkData.title = targetStr;
linkData.url = targetStr;
linkData.range = rg;
[linkArr addObject:linkData];
break;
}
pdex++;
}
}];
return linkArr;
}
如下使用:
NSMutableArray <CTLinkData *>*list = [self matchWebLink:str.string];
[list enumerateObjectsUsingBlock:^(CTLinkData * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
UIFont *font = [UIFont systemFontOfSize:config.textSize];
NSMutableParagraphStyle *para = [[NSMutableParagraphStyle alloc] init];
para.lineBreakMode = config.lineBreakMode;
para.lineSpacing = config.lineSpace;
UIColor *linkColor = [UIColor colorWithCGColor:config.clickStrColor];
NSString *targetStr = [str.string substringWithRange:obj.range];
NSMutableDictionary *attributes = [NSMutableDictionary dictionaryWithDictionary:@{NSForegroundColorAttributeName: linkColor,NSFontAttributeName : font,NSParagraphStyleAttributeName:para}];
NSMutableAttributedString *targetString = [[NSMutableAttributedString alloc] initWithString:targetStr attributes:attributes];
[str replaceCharactersInRange:obj.range withAttributedString:targetString];
}];
return list;
|