经验之谈—正则表达式实现图文混排

40 篇文章 0 订阅
  • 在项目中,我们经常需要发表情,以及经常需要将表情字符转换成表情。因为表情是一个图片,所以我们发给服务器的时候,实际上是发一段特殊的文字给服务器,然后转换成表情。以免浪费用户过多的流量。
  • 那接下来,我们就来介绍一下,如何使用正则表达式实现图文混排呢?
  • 为了以后的代码的管理方便,我们抽取出两个类:

NSString+Regular.h中,我们暴露两个方法出来:

/**
 *  返回正则表达式匹配的第一个结果
 *
 *  @param pattern 正则表达式
 *
 *  @return 匹配的第一个结果 是NSTextCheckingResult类型
 */
- (NSTextCheckingResult *)firstMacthWithPattern:(NSString *)pattern;

- (NSArray <NSTextCheckingResult *> *)machesWithPattern:(NSString *)pattern;

NSString+Regular.m中,我们实现一下这两个方法:


- (NSTextCheckingResult *)firstMacthWithPattern:(NSString *)pattern
{
    //正则表达式的创建很容易失败,注意捕获错误
    NSError *error = nil;
    //根据正则表达式创建实例
    NSRegularExpression *regular = [NSRegularExpression regularExpressionWithPattern:pattern options:0 error:&error];
    if ( error)
    {
        NSLog(@"正则表达式创建失败");

        return nil;
    }
    //匹配出结果
  NSTextCheckingResult *result =   [regular firstMatchInString:self options:0 range:NSMakeRange(0, self.length)];

    if ( result)
    {
        NSLog(@"匹配");
        return result;
    }else
    {
        NSLog(@"不匹配");
        return nil;
    }
}

- (NSArray <NSTextCheckingResult *> *)machesWithPattern:(NSString *)pattern
{
    NSError *error = nil;
    NSRegularExpression *expression = [NSRegularExpression regularExpressionWithPattern:pattern options:0 error:&error];
    if (error)
    {
        NSLog(@"正则表达式创建失败");
        return nil;
    }
    return [expression matchesInString:self options:0 range:NSMakeRange(0, self.length)];


}

我们进而对NSTextAttachment写一个子类
ZYTextAttachment.h 中 我们暴露一个方法出来:

@interface ZYTextAttachment : NSTextAttachment

- (instancetype)initWithImage:(UIImage *)image;

@end

ZYTextAttachment.m中,我们实现一下:

#import "ZYTextAttachment.h"

@implementation ZYTextAttachment

- (instancetype)initWithImage:(UIImage *)image
{
    if (self = [super init])
    {
        self.image = image;
    }
    return self;

}

- (CGRect)attachmentBoundsForTextContainer:(NSTextContainer *)textContainer proposedLineFragment:(CGRect)lineFrag glyphPosition:(CGPoint)position characterIndex:(NSUInteger)charIndex
{
    return CGRectMake(0, -lineFrag.size.height * 0.2, lineFrag.size.height, lineFrag.size.height);
}

这样就能解决图片大写跟文字大小不一致的情况。


接下来,我们在viewController中,

- (void)viewDidLoad {
    [super viewDidLoad];

    self.label.text = @"二货[smiley_2], 你在干嘛呢[smiley_6] 一起吃饭?[smiley_44]!";

}

然后在下面的方法中:

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    NSString *content = self.label.text;
    //匹配表情文字
    NSString *pattern = @"\\[\\w+\\]";

  NSArray *resultArr =   [content machesWithPattern:pattern];
    if (!resultArr) return;

    NSMutableAttributedString *attrContent = [[NSMutableAttributedString alloc]initWithString:content];
    NSUInteger lengthDetail = 0;
    //遍历所有的result 取出range
    for (NSTextCheckingResult *result in resultArr) {
        //取出图片名
      NSString *imageName =   [content substringWithRange:NSMakeRange(result.range.location + 1, result.range.length - 2)];
        // 创建AttributeString, 来包装图片
      ZYTextAttachment *attachment =   [[ZYTextAttachment alloc]initWithImage:[UIImage imageNamed:imageName]];
        // 将附近包装到NSAttributedString中
      NSAttributedString *imageString =   [NSAttributedString attributedStringWithAttachment:attachment];
        //图片附件的文本长度是1
        NSLog(@"%zd",imageString.length);

        NSUInteger length = attrContent.length;
        NSRange newRange = NSMakeRange(result.range.location - lengthDetail, result.range.length);
        [attrContent replaceCharactersInRange:newRange withAttributedString:imageString];

        lengthDetail += length - attrContent.length;

    }
    //更新到label上
    self.label.attributedText = attrContent;
}

看一下效果:
正则

正则表情

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值