美文网首页
iOS 正则表达式切割字符串的应用

iOS 正则表达式切割字符串的应用

作者: woniu | 来源:发表于2018-11-29 15:19 被阅读15次

    背景:近来公司需要做音频书的颜色高亮功能,也就是音频读到哪里,文字也就随着变色。这样的话也就用到了文本的内容切割问题就来了。

    一、字符串的切割

    下面我们展示下我们要切割的部分文本内容:

     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

    相关文章

      网友评论

          本文标题:iOS 正则表达式切割字符串的应用

          本文链接:https://www.haomeiwen.com/subject/xxcfcqtx.html