美文网首页
正则表达式

正则表达式

作者: BigBossZhu | 来源:发表于2016-11-02 21:28 被阅读106次

正则表达式

纯文本做限制处理.可以用来检查一个字符串是否包含某种子串,将匹配的子串做替换或者从某个串中取出符合某个

作用:模式匹配(子串的定位操作),替换,效率高且简单.语法后台玩的比较溜,工作中不会的可以找他们.

  1. 数据验证
  2. 替换文本
  3. 提取子字符串

掌握正则表达式在OC代码中使用.

关键词: Regular Expression(正则表达式)
核心类: NSRegularExpression(NS框架下的,不需要导入):用来表达应用正则表达式.

注意点:

  1. 正则表达式很容易写错,所以一定要做错误处理
  2. 创建正则表达式.
  3. 查找相关内容.

- (void)regularExpression {
    NSString *content = @"蓝瘦, 香菇, 本来今天高高兴兴, 你为什么要说这种话, 蓝瘦, 在这里, 香菇! 第一次喂了一个女孩屎";
    //创建正则对象,配置参数
    // Pattern(模式), 要填的是`正则语法`所组成的`匹配模式`, 作用是告诉正则, 要查找的是什么("蓝瘦")
    NSString *pattren = @"香菇";
    // NSRegularExpressionOptions 正则表达式的匹配查找选项, 通常会给0, 因为正则语法可以实现这此功能
    // 错误处理,必须要做
    NSError *error;
    NSRegularExpression *regular = [NSRegularExpression regularExpressionWithPattern:pattren options:0 error:&error];
    if (error) {
        NSLog(@"创建正则失败");
    }
    
    
    /**
     // 查找第一次匹配结果
     参数一:在哪个字符串中匹配
     参数二:匹配查找选项,选0
     参数三:在这个字符串的哪个范围中匹配
     */
    NSTextCheckingResult *result = [regular firstMatchInString:content options:0 range:NSMakeRange(0, content.length)];
    NSLog(@"%@",NSStringFromRange(result.range));
    NSLog(@"%@",[content substringWithRange:result.range]);
    
    /**
     全部匹配
     参数1 NSString content
     参数2 0
     参数3 content的查找范围
     返回数组 results
     */
    NSArray<NSTextCheckingResult *> *results = [regular matchesInString:content options:0 range:NSMakeRange(0, content.length)];
    //遍历
    for (NSTextCheckingResult *result in results) {
        NSLog(@"%@",NSStringFromRange(result.range));
        NSLog(@"%@",[content substringWithRange:result.range]);
    }
}

目标:掌握一些正则的基本语法
  1. @"55555" -> @"5{5}" 中{}是功能性字符,表示重复5次
  2. @"5{3,7}" :{3,7}表示重复3~7次,会尽量找到多的.
  3. @"5+" :+表示至少有一个,默认只修饰前面一个
  4. @"(123)+" :()加小括号改变优先级,修饰一个整体.
  5. @"[136]" :[]代表组合,可以是其中的任意一个.
  6. 只要含数字: @"[0123456789]+" -> @"[0-9]+".-代表范围
  7. @"\d" :元字符(转义字符),\d在正则当中表示任意整数,\d等价[0-9]
    注意:OC的字符串中,\d正则不能直接写,所以要写\d.
  8. 找到字符:@"[a-z]+"
  9. @"\w":表示\w正则表示字符,汉字下划线,数字.OC中写\w
  10. @"\w和[\w]":在没有[]时,他表示的是匹配字符串的开始.^在[]里面,表示取反,表示并非是这个类型的字符串的开始.
    还要理解一下.
  11. @".com$": $表示匹配到字符串结束.
  12. @"(0|86)?" :表示以0或86或空(?).
  • 注意点
  • OC中\如果要代表字符串必须通过\来转义这个.才能使用.
  • 正则不能留空格,是一个字符在正则中来说是有意思的.pattern参数创建也不能加空格.都不能加空格.所以说错误处理一定要做.
正则练习
// 匹配QQ号码,匹配规则:全部是都是数字,第一个字符非0,长度为(6~11)
     ^[1-9]\\d{5,10}$
    // [^0],[1-9]    \d,[0-9]  {5,10}
    //    NSString *result = [@"48584958" firstStringMatchWithPattern:@"^[1-9]\\d{5,10}$"];
    //    NSLog(@"%@", result);
    
    // 匹配规则:以0或86或空开头,后面第一个数字为"1",当第二数字为 "3,5,8" 第三个数字为"0-9",当第二数字为"7" 第三个数字为"6或7或8",当第二个数字为"4"时,第三个数字为"5或7",手机号码位数为11位.
    // ^ (0|86)? 1 ( ([358][0-9]) | (7[678]) | 4[57] ) \d{8} $
    // ? 表示可有可无, 类似于bool
    NSString *result = [@"13800138000" firstStringMatchWithPattern:@"^(0|86)?1(([358][0-9])|(7[678])|4[57])\\d{8}$"];

提取分类文件保留.

正则实际用法:(重要),研究一下.

一种设计思想(都是用正则做的)
微信中的默认表情包的表情发送情况分析:

  • 表情是图片,图片始终要比文字大的多
  • 表情包在应用上本来就有,没有必要通过网路传输
  • 用一个特殊的字符串来表示表情,将该字符串发送出去
    • 不用发送图片,只发送文字,节省流量
    • 双方的应用本身已经拥有这套表情,可以直接显示出来
  1. 发送方与接收方, 规定一些特定的字符, 用来表示表情 如 [微笑] , /微笑
  2. 发送方: 在发消息之前, 将带有表情的文字转换成纯文字
    如: 你好!约吗(微笑表情) (富文本) --> 你好!约吗[smile.png] (纯文本)
  3. 接收方: 在收到消息后, 显示之前, 会做处理
    如: 你好!约吗[smile.png] --> 你好!约吗(微笑表情)

利用应用名来定义一份协议,再用正则来匹配协议.

微信扫二维码添加好友的思路分析:
微信扫描二维码的字符串
我先子定一个协议以Wechat://Action=Adduser?UserID=科比?message="你好我是谁谁谁,请求验证."

  • 利用正则来检测,是否为Wechat://开头,是的话,进行相应处理.
  1. 假设Action 表示 添加好友, 调用相关代码来实现功能
  2. 假设 UserID 表示添加的好友ID的参数, message 表示添加好友的消息的参数
  3. 调用添加好友的功能代码, 将相关参数给它.

二维码http://跳转网页的思路逻辑:

  • 利用正则来检测, 是否为http协议, 是用safari打开
    1. 获取参数, 利用相关代码, 让safari打开该网页

示例Demo:将表情图片名换成真正的图片名.

实现富文本(带有表情图片):富文本可以带附件NSTextAttachment类.

NSAttributedString

  1. 查找文本 -> 是否有表情图片的文字:正则表达式
  2. 利用富文本实现图文混排.

// [表情名] :[]在正则里面有特殊意义,所以\[表示普通的],正则转义
// [\w+]->转化为OC还要转义@"\[\w+\]"

  1. 正则查找图片格式字符串,获取到这个字符串.

  2. 转化为文字

  3. 富文本显示图片加文字.(替换表情字符串为图片附件字符串)

注意

  1. 表情符号的高度与Lable不匹配的解决办法.自定义类继承NSTextAttachment,一个快速的方法使其高度相等,** 修改它的y值,为-高度*0.2 **

  2. 多张表情图片的替换

注意数组越界问题:原因,因为替换的原理导致你的字符串的range减少,所以产生越界问题.但是还是以原来的来取.
解决办法,** 从尾部替换 **.

// 返回附件在它的容器当中的位置
- (CGRect)attachmentBoundsForTextContainer:(NSTextContainer *)textContainer proposedLineFragment:(CGRect)lineFrag glyphPosition:(CGPoint)position characterIndex:(NSUInteger)charIndex
{
//继承系统的NSTextAttachment类.修改表情使其高度相同
    // 附件所处的容器的大小
    NSLog(@"lineFrag: %@", NSStringFromCGRect(lineFrag));
    // 附件在它的显示容器当中的位置
    NSLog(@"position: %@", NSStringFromCGPoint(position));
    // 附件所处文本在原始文本当中的位置(索引)
    NSLog(@"%zd", charIndex);
    
    // 返回的附件的大小, 与label的高度一样 (与文字接近)
    // 简单粗暴: -lineFrag.size.height * 0.2;  (StackOverFlow)
#pragma mark - 修改表情高度与Lable相同(开始会高一些)
    return CGRectMake(0, -lineFrag.size.height * 0.2, lineFrag.size.height, lineFrag.size.height);
    // 科学合理(不好解释): 要根据字体来决定该值
//    return CGRectMake(0, self.font.descender, lineFrag.size.height, lineFrag.size.height);
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    self.label.text = @"蓝瘦, 香菇[smiley_1], 在这里, 第一次喂了一个女孩屎[smiley_6], 这么香菇[smiley_19]!";
    // 正则表达式只能针对纯文本NSString进行匹配, 不能NSAttributedString
    NSString *content = self.label.text;
    
    NSMutableAttributedString *attrString = [[NSMutableAttributedString alloc] initWithString:content];
    
    // 1. 找到所有的图片(封装好了正则表达式)
    NSArray *rangeArray = [content matchesRangeWithPattern:@"\\[\\w+\\]"];
    if (rangeArray == nil) {
        return;
    }
    
    for (int i = 0; i < rangeArray.count; i++) {
        // 倒过来读取数组的元素
        NSValue *value = rangeArray[rangeArray.count - i - 1];
        // 每一个表情[表情图片]的范围
        NSRange range = value.rangeValue;
        
        // 获取每张图片图片
        UIImage *image = [UIImage imageNamed:[content substringWithRange:NSMakeRange(range.location + 1, range.length - 2)]];
        
        // 创建表情图片对应NSAttributedString
        HMTextAttament *attachment = [[HMTextAttament alloc] init];
        attachment.image = image;
        NSAttributedString *imageString = [NSAttributedString attributedStringWithAttachment:attachment];
        NSLog(@"%zd", imageString.length);
        
        // 替换文本
        [attrString replaceCharactersInRange:range withAttributedString:imageString];
    }
    
    // 已经全部替换完成
    self.label.attributedText = attrString;
}

  • ** 顺便学习一下文字换行和文字大小文字颜色的富文本处理. **
    思路:通过NSAttributedString的子类NSMutableAttributedString,设置前一段的字体属性,可以设置大小,颜色以及换行

** 注意:正则表达式只能匹配纯文本NSString,不能匹配NSAttributedString. **

相关文章

  • Linux命令行与Shell脚本编程大全-shell正则表达式

    本章内容: 定义正则表达式 了解基本正则表达式 扩展正则表达式 创建正则表达式 定义正则表达式 正则表达式是你定义...

  • 正则相关

    正则表达式基本语法 正则表达式常见字符 正则表达式特殊字符 正则表达式数量词 正则表达式边界匹配 正则表达式逻辑或...

  • 正则表达式系列-1

    正则表达式系列-1正则表达式系列-2正则表达式系列-3正则表达式系列-4 什么是正则表达式 正则表达式就是用事先定...

  • 正则表达式

    正则表达式 - 教程正则表达式 - 简介正则表达式 - 语法正则表达式 - 元字符正则表达式 - 运算符优先级正则...

  • Python基础入门 - 正则表达式与综合实战

    1. 初识正则表达式 1.1 介绍 步骤介绍正则表达式入门及应用正则表达式的进阶正则表达式案例 1.2 正则表达式...

  • Java正则表达式参考

    Java正则表达式入门 java正则表达式应用 深入浅出之正则表达式(一) 深入浅出之正则表达式(二) 正则表达式...

  • 正则表达式

    正则表达式 正则表达式就是记录文本规则的代码 正则表达式常用的元字符 正则表达式常用的限定符 正则表达式举例:这里...

  • Python爬虫(十)_正则表达式

    本篇将介绍python正则表达式,更多内容请参考:【python正则表达式】 什么是正则表达式 正则表达式,又称规...

  • python正则表达式

    本篇将介绍python正则表达式,更多内容请参考:【python正则表达式】 什么是正则表达式 正则表达式,又称规...

  • 正则表达式

    了解正则表达式基本语法 能够使用JavaScript的正则对象 正则表达式简介 什么是正则表达式 正则表达式:用于...

网友评论

      本文标题:正则表达式

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