正则表达式的注意点

先说遇到的问题,

  const numberRegexp = /\d+/g;
  const isNumber = (v) => numberRegexp.test(v);
  isNumber('22'); // true
  isNumber('22'); // false

惊呆了,不是同一个正则吗?怎么可能啊?

全局匹配(g)

上面的问题就是使用了全局匹配,带来的影响.如果正则表达式设置了全局标志,test() 的执行会改变正则表达式lastIndex属性。连续的执行test()方法,后续的执行将会从 lastIndex 处开始匹配字符串,(exec() 同样改变正则本身的 lastIndex属性值).
lastIndex是用来指定下一次匹配的起始索引

  const numberRegexp = /\d+/g;
  const isNumber = (v) => numberRegexp.test(v);
  isNumber('22'); // true
  // but numberRegexp.lastIndex 2
  isNumber('22'); // false
  // 所以后面的匹配从2开始,后面自然就是找不到匹配了就是false
正则的lastIndex

只有正则表达式使用了表示全局检索的 “g” 标志时,该属性才会起作用。此时应用下面的规则:

  • 如果 lastIndex 大于字符串的长度,则 regexp.test 和 regexp.exec 将会匹配失败,然后 lastIndex 被设置为 0。
  • 如果 lastIndex 等于字符串的长度,且该正则表达式匹配空字符串,则该正则表达式匹配从 lastIndex 开始的字符串。
  • 如果 lastIndex 等于字符串的长度,且该正则表达式不匹配空字符串 ,则该正则表达式不匹配字符串,lastIndex 被设置为 0.。
  • 否则,lastIndex 被设置为紧随最近一次成功匹配的下一个位置。

正则相关的修饰符

修饰符i

修饰符i 就是忽略大小写的修饰符

修饰符m

修饰符m 修饰符 是多行修饰符; 将开始和结束字符(^和$)视为在多行上工作(也就是,分别匹配每一行的开始和结束(由 \n 或 \r 分割),而不只是只匹配整个输入字符串的最开始和最末尾处。

修饰符u

修饰符u 修饰符,将模式视为Unicode序列点的序列, 是对UTF-16编码的支持,ES5的时候,还不支持UTF-16, 对于码点大于0xFFFF的Unicode字符,不能识别,必须加上u修饰符。

  const a = "𠮷";
  /^.$/.test(a);  // false
  /^.$/u.test(a); // true

  /[a-z]/i.test('\u212A') // false \u212A是非规范的K字符
  /[a-z]/iu.test('\u212A') // true
修饰符y

修饰符y 与g修饰符类似,也是全局匹配,后一次匹配都是从上一次匹配成功的下一个位置开始。区别在于,g修饰符只要剩余位置中存在匹配即可,而y修饰符是必须从剩余第一个开始。

  const s = 'aaa_aa_a';
  const r1 = /a+/g;
  const r2 = /a+/y;

  r1.exec(s) // ["aaa"]
  r2.exec(s) // ["aaa"]

  r1.exec(s) // ["aa"]  剩余 '_aa_a' r1 只要剩下的匹配到就好了
  r2.exec(s) // null // 必须冲第一个开始,第一个是_,所以匹配不上
修饰符s
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值