RegExp.prototype.test()与g的使用

在进行日期校验时遇到的问题与正则表达式的全局标志`g`有关。`test()`和`exec()`方法在全局模式下会改变`lastIndex`属性,导致连续校验失败。解决方案是移除全局标志,避免`lastIndex`影响后续匹配。
摘要由CSDN通过智能技术生成

test校验问题

最近做日期校验遇到了一个问题,总是除了第一次输出为true,其余总为false 具体看下图
在这里插入图片描述

解决办法

按照我的思路,以上test都应该返回true,但事实上不是,所以去问答社区提问,得到了答案:

需要去掉gg是全局标志,test()的执行会改变正则表达式 lastIndex属性。连续的执行test()方法,后续的执行将会从 lastIndex 处开始匹配字符串,exec()同样改变正则本身的 lastIndex 属性值).

  1. 第一次校验: reg.lastIndex is at 0reg.test(’2022/04/03’)返回了true
  2. 第二次校验:reg.lastIndex is now at 10reg.test(’2022年04月03日’)返回了false
  3. 第三次校验:lastIndex长度大于字符长度,reg.lastIndex is at 0 ,返回true
  4. 同理校验,第四次也返回了false

官网是这样子解释的:

using test on regex with global flag

When a regex has the global flag set, test() will advance the lastIndex of the regex. (RegExp.prototype.exec() also advances the lastIndex property.)

Further calls to test(str) will resume searching str starting from lastIndex. The lastIndex property will continue to increase each time test() returns true.

Note: As long as test() returns true, lastIndex will not reset—even when testing a different string!

When test() returns false, the calling regex’s lastIndex property will reset to 0.

The following example demonstrates this behavior:

const regex = /foo/g; // the "global" flag is set

// regex.lastIndex is at 0
regex.test('foo')     // true

// regex.lastIndex is now at 3
regex.test('foo')     // false

// regex.lastIndex is at 0
regex.test('barfoo')  // true

// regex.lastIndex is at 6
regex.test('foobar')  //false

// regex.lastIndex is at 0
// (...and so on)

RegExp表达式

let reg=/^\d{4}\D\d{1,2}\D\d{1,2}\D?$/g
  • pattern:任何简单或复杂的正则表达式,包括字符类、限定符、分组、向前查找以及反向引用
  • flags:一个或者多个标志,用以标明正则表达式的行为

flags常用3个标志:

  • g:表示全局(global)模式,即模式将被应用于所有字符串,而非在发现第一个匹配项时立即停止
  • i:表示忽略大小写(case-insensitive)模式,即在确定匹配项时忽略模式与字符大小写
  • m:表示多行(multiline)模式,即在到达一行文本末尾时,还会查找下一行中是否存在与模式相互匹配的项

reg用到的元字符含义

元字符含义
^从字符串开始位置匹配
$从字符串结束位置匹配
\d匹配一个数字字符。等价于 [0-9]
\D匹配一个非数字字符。等价于 [^0-9]
{n}n 是一个非负整数。匹配确定的 n 次。例如,‘o{2}’ 不能匹配 “Bob” 中的 ‘o’,但是能匹配 “food” 中的两个 o
{n,m}m 和 n 均为非负整数,其中n <= m。最少匹配 n 次且最多匹配 m 次。例如,“o{1,3}” 将匹配 “fooooood” 中的前三个 o。‘o{0,1}’ 等价于 ‘o?’。请注意在逗号和两个数之间不能有空格
?当该字符紧跟在任何一个其他限制符 (*, +, ?, {n}, {n,}, {n,m}) 后面时,匹配模式是非贪婪的。非贪婪模式尽可能少的匹配所搜索的字符串,而默认的贪婪模式则尽可能多的匹配所搜索的字符串。例如,对于字符串 “oooo”,‘o+?’ 将匹配单个 “o”,而 ‘o+’ 将匹配所有 ‘o’

RegExp.lastIndex

lastIndex 是正则表达式的一个可读可写的整型属性,用来指定下一次匹配的起始索引

描述

正则表达式使用了全局检索g或者粘性检索y标志,该属性才会生效,应用规则如下:

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

示例

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值