背景:近来公司需要做音频书的颜色高亮功能,也就是音频读到哪里,文字也就随着变色。这样的话也就用到了文本的内容切割问题就来了。
一、字符串的切割
下面我们展示下我们要切割的部分文本内容:
NSString *textString = @"###弗洛伦蒂诺·阿里萨选择了这个时候向乌尔比诺的妻子费尔米娜·达萨
表白了心迹,但是她被他的唐突,以及自己所感到的内心深处触发出的情感所吓退。当他们都年轻
的时候,她和弗洛伦蒂诺互相交换了许多炽热的情书,并且曾经决定结婚。而再次见到他时,费尔明
娜却“惊慌地自问,怎么会如此残酷地让那样一个幻影在自己的心间占据了那么长时间”,并对他说
“忘了吧”。弗洛伦蒂诺则珍守着对她的渴望,并且决心为她保持童贞直到他们最终能够走到一起。
然而他很快发现自己用放纵的生活来排遣分离的空虚,费尔米娜嫁给了乌尔比诺医生?成为了他忠实
的伴侣。而医生本人也有着相似但比较简短的一段前事。";
从文本上看,我们获取需要获取每一段的句子,然后在获取每一句的字符长度,于是我想到了字符串的切割,如下:
NSArray *array = [textString componentsSeparatedByString:@"。"]; //从字符A中分隔成2个元素的数组
NSString *str = array[0];
//这里的句号、逗号、引号等等都算在了长度里面。
NSLog(@"~~~~~~~~~~~text:%@~~~~~~~length:%ld",str,str.length);
NSMutableArray *numberArr = [NSMutableArray arrayWithCapacity:10];
for (int i=0; i<array.count; i++) {
NSString *text = array[i];
NSString *textLength = [NSString stringWithFormat:@"%lu",(unsigned long)text.length];
if ((unsigned long)text.length > 0) {
[numberArr addObject:textLength];
}
}
NSLog(@"所有字段的文字长度:%@",numberArr);
输入结果如下:
2018-11-29 14:48:35.512699+0800 Test1[21667:780226] ~~~~~~~~~~~text:###弗洛伦蒂诺·
阿里萨选择了这个时候向乌尔比诺的妻子费尔米娜·达萨表白了心迹,但是她被他的唐突,以及自己所
感到的内心深处触发出的情感所吓退~~~~~~~length:70
2018-11-29 14:48:35.513002+0800 Test1[21667:780226] 所有字段的文字长度:(
70,
38,
60,
37,
47,
20
)
二、正则表达式的切割
但是,实际场景是我们会以。、~、?、——等符号来判定为一句话。这样的话,我们如果还使用字符串的切割也可以,但是需要根据不同的符号遍历所有的数据,然后还要把数据拼接起来,这样的话整个步骤就显得非常的繁琐。于是,正则表达式就显示出它的优点了。
下面是正则表达式的处理方法:
1、(?<=?|。|,|###) 开始的字符标识。 ?<=反向肯定预查,是倒着查找设定的数据。和?>=相反,但是结果不同,所有的符号都会显示出来,且是开头的符号。
2、(.*?) 匹配零次、或多次。尽可能少的匹配,即懒惰模式(laziness)。
3、(?=?|。)结束的字符串 实际会消除掉结尾的标点符号 如果是使用 (?|。),那么符号还是会在结尾处保留的。
NSString *regexStr = @"(?<=?|。|###|,)(.*?)(?|。)";
NSArray *regArr = [self matchString:textString toRegexString:regexStr];
NSLog(@"~~~~~~~~~~regArr:%ld",regArr.count);
for (int i=0; i<regArr.count; i++) {
NSString *str = regArr[i];
NSLog(@"分割之后的正则表达式的内容为:%@~~~~~~~~字数:%lu",regArr[i],(unsigned long)str.length);
}
封装成类的的处理方式:
- (NSArray *)matchString:(NSString *)string toRegexString:(NSString *)regexStr
{
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:regexStr options:NSRegularExpressionCaseInsensitive error:nil];
NSArray * matches = [regex matchesInString:string options:0 range:NSMakeRange(0, [string length])];
//match: 所有匹配到的字符,根据() 包含级
NSMutableArray *array = [NSMutableArray array];
for (NSTextCheckingResult *match in matches) {
for (int i = 0; i < [match numberOfRanges]; i++) {
//以正则中的(),划分成不同的匹配部分 这里会莫名其妙的遍历两次,导致输出两个
相同的数据,我们可以像下面这样只取第一个值,也可以不进行遍历,直接取出来第一
个值。
NSLog(@"~~~~~~~~~~~~[match numberOfRanges]:%lu",(unsigned long)[match numberOfRanges]);
if (i == 0) {
NSString *component = [string substringWithRange:[match rangeAtIndex:i]];
[array addObject:component];
}
}
}
return array;
}
我们使用 (?|。)打印输入内容,可以看到,都包含尾部的标点,如果我们使用(?=?|。)那么标点符号会被清除掉:
2018-11-29 15:05:21.338177+0800 Test1[21812:788917] 分割之后的正则表达式的内容为:
弗洛伦蒂诺·阿里萨选择了这个时候向乌尔比诺的妻子费尔米娜·达萨表白了心迹,但是她被他的唐突,
以及自己所感到的内心深处触发出的情感所吓退。~~~~~~~~字数:68
2018-11-29 15:05:21.338315+0800 Test1[21812:788917] 分割之后的正则表达式的内容为:当
他们都年轻的时候,她和弗洛伦蒂诺互相交换了许多炽热的情书,并且曾经决定结婚。~~~~~~~~字数
:39
2018-11-29 15:05:21.428182+0800 Test1[21812:788917] 分割之后的正则表达式的内容为:而
再次见到他时,费尔明娜却“惊慌地自问,怎么会如此残酷地让那样一个幻影在自己的心间占据了那么
长时间”,并对他说“忘了吧”。~~~~~~~~字数:61
2018-11-29 15:05:21.428674+0800 Test1[21812:788917] 分割之后的正则表达式的内容为:弗
洛伦蒂诺则珍守着对她的渴望,并且决心为她保持童贞直到他们最终能够走到一起。~~~~~~~~字数:
38
2018-11-29 15:05:21.428790+0800 Test1[21812:788917] 分割之后的正则表达式的内容为:然
而他很快发现自己用放纵的生活来排遣分离的空虚,费尔米娜嫁给了乌尔比诺医生?~~~~~~~~字数:
38
2018-11-29 15:05:21.428890+0800 Test1[21812:788917] 分割之后的正则表达式的内容为:成
为了他忠实的伴侣。~~~~~~~~字数:10
2018-11-29 15:05:21.428979+0800 Test1[21812:788917] 分割之后的正则表达式的内容为:而
医生本人也有着相似但比较简短的一段前事。~~~~~~~~字数:21
三、文字的变色
下面我们写一个示例来展示文字变色的处理过程:
使用定时器,定时获取数据,根据数据来判定需要变色的起始位置和范围。
__block int i=0;
[NSTimer scheduledTimerWithTimeInterval:2 repeats:YES block:^(NSTimer * _Nonnull timer) {
NSMutableAttributedString *mAttStr = [[NSMutableAttributedString alloc] initWithString:self.textString];
//1、获取段落设置的全部内容
for (NSString *key in [self.paragraphAttributes allKeys]) {
NSValue *value = self.paragraphAttributes[key];
[mAttStr addAttribute:key
value:value
range:NSMakeRange(0, self.textString.length)];
}
/*
2、遍历取出来富文本参数数组内容(ConfigAttributedString对象的数组):
1、addAttribute : 富文本属性
2、value : 富文本值
3、range : 富文本范围
*/
for (int count = 0; count < _attributes.count; count++) {
ConfigAttributedString *oneConfig = _attributes[count];
[mAttStr addAttribute:oneConfig.attribute
value:oneConfig.value
range:oneConfig.range];
}
[mAttStr addAttribute:NSForegroundColorAttributeName value:[UIColor redColor] range:NSMakeRange(10*i, 10)];
self.textView.attributedText = mAttStr;
++i;
}];
正则表达语法:https://www.jianshu.com/p/3323adcff24f
正则表达常见的使用:http://www.cnblogs.com/XYQ-208910/p/6056646.html
网友评论