正则表达式--反向引用与正向预查

正则表达式–学习笔记

正则表达式,是一种对字符串操作的逻辑公式,就是用事先定义好的一些特定字符、及这些特定字符的组合,组成一个“规则字符串”,这个“规则字符串”用来表达对字符串的一种过滤逻辑。—-真真是个好东西

But , 那些规则真的不好记住,稍微要实现点复杂功能,就得翻箱倒柜找笔记,找度娘,很费时间。。。

废话真多,开始正题!

1 常用符号

  • ^ 匹配输入字符串的开始位置
  • + 匹配一个或多个字符(至少要有一个)
  • $ 匹配输入字符串的结束位置
  • * 匹配0个或多个字符串(可以没有,也可以有)
  • ? 最多出现一次
  • \ 转义
  • . 除换行之外的任何字符
  • | 指明两项之间选择一项
/^c/                => 匹配'c'开头的字符串
/^cm+/              => 匹配'cm'开头的字符串
/^cm+k$/            => 匹配'cmk','cmmmmk'中间不能有其他字符
/^cm+a+b*k$/        => 匹配'cmak', 'cmmmaaak', 'cmmmaaaabbbbk'/^cma?k$/           => 匹配'cmak''cmk'
/^cm\\+k$/          => 匹配'cm\k','cm\\\k'/^cm.*k$/           => 匹配'cm'开头,'k'结尾的字符串
/^cm|hk$/           => 匹配'cmk','chk'

2 转义字符

  • \f 匹配一个换页符
  • \n 匹配换行符
  • \r 匹配回车符
  • \s 匹配任何空白字符,如空格,制表符,换页符等
  • \S 匹配任何非空白字符
  • \t 匹配制表符
  • \v 匹配垂直制表符
  • \d 匹配数字
  • \D 匹配非数字
  • \w 匹配下划线在内的任何单词字符:_ A-Z a-z 0-9
  • \b 匹配字符边界,字符与空格之间的位置
/\b[\w]+\b/   // 匹配出一个单词

3 表达式

  • [ ] 中括号表达式,字符集
/^c[0-9]+k$/          =>匹配'c'开头,'k'结尾,中间至少有一个数字的字符串
/^c[0-9A-Z]+k$/       =>匹配'c'开头,'k'结尾,中间至少有一个数字或大写字母的字符串
/^c[0-9A-Za-z_]+k$/   => 等价于 /^c\w+k$/ 
/^c[^0-9]+k$/         => 中括号内的^表示除此集合之外的字符
  • {} 限定出现次数
/^[0-9]{6}$/          => 匹配6位数字
/^[0-9]{4,6}$/        => 匹配46位数字
  • () 子表达式,可以看成一个字符,具体后面讲

4 示例解析

/^(-|\+)?[1-9][0-9]*(\.[0-9]{1,6})?$/

// 匹配可带正负号的实数(+-1.0之间的小数无法匹配,尴尬)
// (-|\+)         表示匹配'-'或者'+',由于'+'具有特定含义,需要转义
// ()?            表示括号内匹配的内容最多出现一次
// [1-9][0-9]*    表示匹配1-9打头的多位数字
// \.[0-9]{1,6}   表示匹配1到6位小数部分,'.'需要转义
// 这个表达式可以匹配可带正负号,最多6位小数的实数,但是不能匹配出±1.0之间的小数,略显尴尬,主要原因是这里强制要求数字首位必须是1-9,这样做的原因不匹配这样的数字: 000123.56
// 为了解决这个问题,可以加个选择条件([1-9][0-9]*)|0, 开头可以有一个0

/^(-|\+)?(([1-9][0-9]*)|0)(\.[0-9]{1,6})?$/   // 完美解决了

5 捕获组

捕获组就是把正则表达式中子表达式匹配的内容,保存到内存中以数字编号或显式命名的组里,方便后面引用。

5.1 普通捕获组:(expression)
  • 编号规则:按照’(‘编号出现的顺序,从左到右,从1开始编号
(\d{4})-(\d{2}-(\d\d))
// 捕获组1:\d{4}
// 捕获组2:\d{2}-(\d\d)
// 捕获组3:\d\d
5.2 命名捕获组:(?\expression)
  • 编号规则:可按name引用,也可按编号引用,编号规则也是按’(‘出现的顺序开始编号
    当两者混用时,先给普通捕获组编号,再给命名捕获组编号
(\d{4})-(?<date>\d{2}-(\d\d))
// 捕获组1:\d{4}
// 捕获组2:\d\d
// 捕获组3:(?<date>\d{2}-(\d\d))

6 反向引用

捕获组捕获到的内容在正则表达式内部进行引用,则为反向引用
  • 通过编号引用: \number, 如 \1, \2
  • 通过命名引用: \k\
/(ab)\1/      // 匹配'abab', \1表示(ab)匹配到的内容
/(ab)\1{2}/   // 匹配'ababab', \1表示(ab)匹配到的内容

7 正向预查

正向匹配: (?=pattern)

正向不匹配: (?!pattern)’

/\b[\w]+(?=ing\b)/   

// 匹配的字符串满足'\b[\w]+',而且后面需要跟ing
// 符合此规则的字符串有:coming,going,但comingx 不符合

8 正则表达式用法

正则表达式最基本的用法有验证字符串是否合法提取子字符串
应用场景1:验证表单—验证邮箱是否合法

/^\w+@\w+\.\w+$/     // 匹配**@**.**这种类型

应用场景2:提取html中img元素的src和name的值

示例字符串:

<img alt="" border="0" name="g6-o44-1" onload="DrawImage" src="/bmp/foo1.jpg" />

表达式:

/<img\b(?=(?:(?!name=).)*name=(['"]?)([^'"\s>]+)\1)(?:(?!src=).)*src=(['"]?)([^'"\s>]+)\3[^>]*>/i
// 捕获组里面\2 和 \4分别为name和src的值

上述表达式如何理解呢?

  • 首先,先把正向预查删了,更好理解,如下:
/<img\b(?:(?!src=).)*src=(['"]?)([^'"\s>]+)\3[^>]*>/i
  • (?:(?!src=).)* 这个表示不包含子串’src=’和’\n’的任意字符
  • ([‘”]?)([^’”\s>]+)\3 中,\3 表示的就是([‘”]?)匹配的结果,组合起来就是’**’,”**”或**,那么中间的就是匹配src的值了,([^’”\s>]+), 排除掉了’,”,空白字符以及’>’,这样就顺利把src的值取到了。
  • 那怎么取name的值呢,因为name和src的相对位置可能不同,所以不知直接套用取src的方法了,这里采用了正向预查的方法,其实也跟取src的值原理一样,不过是放在预查里面
(?=(?:(?!name=).)*name=(['"]?)([^'"\s>]+)\1)

9 修饰符

  • i 表示不区分大小写
  • g 全局搜索(查找所有匹配而非在找到第一个匹配后停止)
  • m 多行匹配

10 Javascript中正则表达式的应用

10.1 RegExp对象

表示正则表达式,它是对字符串执行模式匹配的强大工具。
- 方法:test() 用于检测字符串是否匹配该表达式,匹配成功则返回true
- 方法:exec() 用于检索字符串中的正则表达式的匹配
- 属性:$n n表示1-99,取捕获组的值

var patt = /<img\b(?=(?:(?!name=).)*name=(['"]?)([^'"\s>]+)\1)(?:(?!src=).)*src=(['"]?)([^'"\s>]+)\3[^>]*>/i;
var str = '<img alt="" border="0" name="g6-o44-1" onload="DrawImage" src="/bmp/foo1.jpg" />';
var result patt.test(str);
if (result) {
  console.log(RegExp.$2);  // g6-o44-1
  console.log(RegExp.$4);  // /bmp/foo1.jpg
}

var res = patt.exec(str);
console.log(res[0]);  // 匹配出的字符串
console.log(res[1]);  // RegExp.$1
console.log(res[2]);  // RegExp.$2
console.log(res[3]);
console.log(res[4]);
console.log(res.index);  //开始匹配的地方
console.log(res.input);  //输入字符串
10.2 字符串对象对正则表达式的支持
  • search()
  • replace()
  • match(), 等同于RegExp的exec方法
  • split(), 分割字符串,分隔符可用正则表达式
  • 15
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值