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

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

一、字符串的切割

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

 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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,607评论 6 507
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,239评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,960评论 0 355
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,750评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,764评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,604评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,347评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,253评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,702评论 1 315
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,893评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,015评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,734评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,352评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,934评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,052评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,216评论 3 371
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,969评论 2 355

推荐阅读更多精彩内容