现在APP开发对效果要求越来与丰富,各种特效层出不穷。其中以动画效果和文字以富文本展示居多。
在网上也看了好几种方法,感觉有的处理的麻烦了,下面是我总结的获取子字符串所有Rang的一些方法:
字符串做富文本处理需要通过NSMutableAttributedString来处理,先创建一个NSMutableAttributedString对象:
NSMutableAttributedString *attribtStr = [[NSMutableAttributedString alloc] initWithString:@"父字符串"];
1、使用NSRegularExpression来处理
//初始化NSRegularExpression NSRegularExpression *regularExpression = [NSRegularExpression regularExpressionWithPattern:@"你的正则表达式" options:0 error:nil]; //遍历字符串,usingBlock中返回子字符串的状态,在usingBlock中处理子字符串[regularExpression enumerateMatchesInString:attribtStr.string options:0 range:NSMakeRange(0, attribtStr.string.length) usingBlock:^(NSTextCheckingResult * _Nullable result, NSMatchingFlags flags, BOOL * _Nonnull stop) { //给子字符串添加双删除线 [attribtStr addAttribute:NSStrikethroughStyleAttributeName value:[NSNumber numberWithInteger:NSUnderlineStyleDouble] range:result.range]; //删除线设置为红色 [attribtStr addAttribute:NSStrikethroughColorAttributeName value:[UIColor redColor] range:result.range]; }];
上面方法是直接在遍历中处理匹配的子字符串,下面的是先得到所有子字符串的状态集,再做对应处理:
NSArray *regularExpressionArr = [regularExpression matchesInString:attribtStr.string options:0 range:NSMakeRange(0, attribtStr.string.length)];
得到子字符串的数组集合,需要做什么处理,通过循环判断就可以完成了。
for (NSTextCheckingResult *result in regularExpressionArr) { NSRange rang = [result range]; NSLog(@"%lu",rang.location); [attribtStr addAttribute:NSStrikethroughStyleAttributeName value:[NSNumber numberWithInteger:NSUnderlineStyleDouble] range:result.range]; [attribtStr addAttribute:NSStrikethroughColorAttributeName value:[UIColor redColor] range:result.range]; }
NSRegularExpression的下面几个方法在其他情况下也是很好用的:
//获取子字符串数目- (NSUInteger)numberOfMatchesInString:(NSString *)string options:(NSMatchingOptions)options range:(NSRange)range; //获取第一个子字符串的NSTextCheckingResult- (nullable NSTextCheckingResult *)firstMatchInString:(NSString *)string options:(NSMatchingOptions)options range:(NSRange)range; //获取指定rang内第一个符合要求的子字符串- (NSRange)rangeOfFirstMatchInString:(NSString *)string options:(NSMatchingOptions)options range:(NSRange)range;
2.通过递归获得所有子字符串的rang数组(递归的优缺点就不在扯了,慎用)
//通过递归获取所有子字符串location - (void)rangeOfString:(NSString*)searchString fatherString:(NSString*)fatherStr options:(NSStringCompareOptions)mask range:(NSRange)rangeOfReceiverToSearch { //获取指定范围内第一个匹配的子字符串rang,和上面NSRegularExpression的一个方法效果一样NSRange rang = [fatherStr rangeOfString:searchString options:mask range:rangeOfReceiverToSearch];//判断搜寻范围来决定是否完成搜寻 if (rang.location >fatherStr.length - searchString.length) { return; }//NSRang不能存储在数组中,所以这里存的是rang的location [strLocationRangArr addObject:[NSNumber numberWithInteger:rang.location]];//递归搜寻 [self rangeOfString:searchString fatherString:fatherStr options:mask range:NSMakeRange(rang.location+searchString.length, fatherStr.length-rang.location-searchString.length)]; }
调用示例:
strLocationRangArr = [NSMutableArray array]; [self rangeOfString:@"CoreText" fatherString:attribtStr.string options:0 range:NSMakeRange(0, attribtStr.string.length)]; for (NSNumber *location in strLocationRangArr) { [attribtStr addAttribute:NSStrikethroughStyleAttributeName value:[NSNumber numberWithInteger:NSUnderlineStyleDouble] range:NSMakeRange([location integerValue], 8)]; [attribtStr addAttribute:NSStrikethroughColorAttributeName value:[UIColor redColor] range:NSMakeRange([location integerValue], 8)]; }
3.通过字符串- (NSArray<NSString *> *)componentsSeparatedByString:(NSString *)separator;方法获得的切割数组处理获得子字符串rang集合。
NSArray *arr = [attribtStr.string componentsSeparatedByString:@"searchString"];
通过数组的子字符串去匹配attribtStr.string获取searchString的location,
这种方法需要处理的地方比较多,首先要考虑arr中第一个、最后一个和连续的是否是@“”,在着就是数组中不可避免会出现相同切割为相同的子串。
例如:@“123654789123654789”这样要[email protected]“654”就会出现两个@“123”和@“789”,在判断的时候要在此处处理重复问题,小的表示有了上面两种方法就没有在对这种想法再做深入的实现。
相对NSRegularExpression的简单快速的,其他方法用来作为思路还是不错的。
时间: 2024-10-26 16:45:30