iOS开发-------文字表情(NSAttributeString 属性字符串 以及 NSRegularExpression 正则表达类)

版权声明:本文为博主原创文章,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接。 https://blog.csdn.net/RunIntoLove/article/details/48802883

       之前,无论是微博还是QQ,从网络请求下来的字符串总会看到[大笑]类似的文字表情,一直无法解析,因为之前也一直想解析,但是一直被正则表达式所困,因为不会啊,今天刚好学到了这一部分,为了强烈对比一下,第一张是处理前,第二张是处理后。




      首先正则表达式,楼主依旧表示不会,但是在工作中想用正则表达式的时候,可以让学网页的同胞们求救,作为程序员只要稍微能看得懂即可,推荐一个网址,稍微了解一下正则表达式也是不错的,下面是楼主稍微了解正则表达式的网址

http://deerchao.net/tutorials/regex/regex.htm



      然后就需要了解一下什么叫做属性字符串了,NSAttributeString(不可变属性字符串)以及NSMutableAttributeString(可变属性字符串),举个简单的例子,比如在一个label上,显示一段字符串@“我是中国人”,"中国人“这三个字要红色,“我是”两个字是蓝色的,在一般的label上是没有办法处理的,因为设置颜色是统一的,那用属性字符串来实现以下。

      首先用storyboard拖入一个label组件,位置居中,字体居中,拖入viewController中形成输出口,接着上一下代码,这个例子是及其简单的,更多了解,也请去这一个网址:

  http://blog.csdn.net/ys410900345/article/details/25976179

下面来看一下viewController中的代码

- (void)viewDidLoad {
    [super viewDidLoad];
    
    //测试字符串
    NSString * textString = @"我是中国人";
    
    //转成属性字符串
    NSMutableAttributedString * attributeString = [[NSMutableAttributedString alloc]initWithString:textString];
    
    //设置文字属性,前2个字符的字体颜色设置为蓝色
    [attributeString addAttribute:NSForegroundColorAttributeName value:[UIColor blueColor] range:NSMakeRange(0, 2)];
    //设置文字属性,后三个字符的字体颜色设置为红色
    [attributeString addAttribute:NSForegroundColorAttributeName value:[UIColor redColor] range:NSMakeRange(2, 3)];

    //在标签上显示,注意的是,是label的attributeText属性,不是text属性
    self.lblText.attributedText = attributeString;
    
}

效果如下


更多用法,也可以去上面的博客去学习一下



      回归正题,文字表情,因为无论是QQ还是微博,文字表情的解析不可能是在网络上请求,然后返回的,而是在本地解析了,既然在本地解析,那么就需要本地文件,楼主用的是plist文件,总体是一个数组,数组的每一个元素都是字典




首先定义两个属性,一个是stroyboard上的label的输出口,一个是通过读取本地plist文件存取数据的数组,如下

//
//  ViewController.m
//  正则表达式
//
//  Created by YueWen on 15/9/29.
//  Copyright (c) 2015年 YueWen. All rights reserved.
//

#import "ViewController.h"

@interface ViewController ()

@property (strong, nonatomic) IBOutlet UILabel *lblText;//label的输出口

@property(nonatomic,strong)NSArray * pictureArray;//存储plist文件数据的数组

@end


首先加载plist,是通过路径加载,这些都不是重点,相信能学到这里,本地文件,特别是plist的加载都不会生疏

    //加载数组
    NSString * path = [[NSBundle mainBundle]pathForResource:@"emoticons" ofType:@"plist"];
    self.pictureArray = [NSArray arrayWithContentsOfFile:path];

然后就是生成测试的字符串了

//模拟测试字符串
    NSString * str = @"[兔子]兔子 [熊猫]熊猫  [耶]耶";

接下来就是变成 属性字符串 以及 正则表达式 的参数字符串

    //转成可变属性字符串
    NSMutableAttributedString * mAttributedString = [[NSMutableAttributedString alloc]initWithString:str];
    
    //创建匹配正则表达式的类型描述模板
    NSString * pattern = @"\\[[a-zA-Z0-9\\u4e00-\\u9fa5]+\\]";

然后建立匹配对象

    //创建匹配对象
    NSError * error;
    NSRegularExpression * regularExpression = [NSRegularExpression regularExpressionWithPattern:pattern options:NSRegularExpressionCaseInsensitive error:&error];
    
    //判断
    if (!regularExpression)//如果匹配规则对象为nil
    {
        NSLog(@"正则创建失败!");
        NSLog(@"error = %@",[error localizedDescription]);
        return ;
    }

因为属性字符串的替代是通过范围也就是(NSRange)来实现的,所以解析后的数组里面必然存着range

但是替换的时候需要注意一点,就是如果按照顺序替换,那么后面的range就会被打乱,从而出现各种错误,所以是逆序遍历替换的,话不多说。看代码应该会很清晰。

    //匹配对象成功
    //获取匹配结果的数组
    /**
     *  获取匹配结果的数组
     *
     *  @param NSString 解析字符串
     *
     *  @param range    需要解析的范围
     *
     *  @return 解析后的数组,数组里存着范围range
     */
    NSArray * resultArray = [regularExpression matchesInString:mAttributedString.string options:NSMatchingReportCompletion range:NSMakeRange(0, mAttributedString.string.length)];
    
    //开始遍历 逆序遍历
    for (NSInteger i = resultArray.count - 1; i >= 0; i --)
    {
        //获取检查结果,里面有range
        NSTextCheckingResult * result = resultArray[i];
        
        //根据range获取字符串
        NSString * rangeString = [mAttributedString.string substringWithRange:result.range];
        
        //获取图片
        UIImage * image = [self getImageWithRangeString:rangeString];//这是个自定义的方法
        
        
        if (image != nil)
        {
            //创建附件对象
            NSTextAttachment * imageTextAttachment = [[NSTextAttachment alloc]init];
            //设置图片属性
            imageTextAttachment.image = image;
            
            //根据图片创建属性字符串
            NSAttributedString * imageAttributeString = [NSAttributedString attributedStringWithAttachment:imageTextAttachment];
            
            //开始替换
            [mAttributedString replaceCharactersInRange:result.range withAttributedString:imageAttributeString];
            
        }
    }
    
    //处理完毕后显示在label上
    self.lblText.attributedText = mAttributedString;



楼主有点强迫症,因为里面会有多个循环,所以看着很不爽,所以自定义了一个方法,就是在上面注释的方法,实现如下

//根据rangeString获取plist中的图片
-(UIImage *)getImageWithRangeString:(NSString *)rangeString
{
    //开始遍历
    for (NSDictionary * tempDict in self.pictureArray)
    {
        if ([tempDict[@"chs"] isEqualToString:rangeString])
        {
            //获得字典中的图片名
            NSString * imageName = tempDict[@"png"];
            
            //根据图片名获取图片
            UIImage * image = [UIImage imageNamed:imageName];
            
            //返回图片
            return  image;
        }
    }
    
    return nil;
}


文字匹配表情完成,收工。



阅读更多
换一批

没有更多推荐了,返回首页