RegExp.prototype.sticky
sticky
的访问器属性 RegExp
实例返回正则表达式是否使用 y
标志。
试试看
描述
如果使用了 y
标志,则 RegExp.prototype.sticky
的值为 true
;否则为 false
。y
标志表示正则表达式仅尝试从 lastIndex
属性指示的索引匹配目标字符串(并且与全局正则表达式不同,不尝试从任何后面的索引匹配)。
sticky
的设置访问器为 undefined
。无法直接更改此属性。
对于粘性正则表达式和 全局 正则表达式
- 它们从
lastIndex
开始匹配。 - 当匹配成功时,
lastIndex
将提前到匹配的末尾。 - 当
lastIndex
超出当前匹配字符串的范围时,lastIndex
将重置为 0。
但是,对于 exec()
方法,匹配失败时的行为有所不同
- 当在粘性正则表达式上调用
exec()
方法时,如果正则表达式在lastIndex
处无法匹配,则正则表达式会立即返回null
并将lastIndex
重置为 0。 - 当在全局正则表达式上调用
exec()
方法时,如果正则表达式在lastIndex
处无法匹配,它会尝试从下一个字符开始匹配,依此类推,直到找到匹配或到达字符串末尾。
对于 exec()
方法,既是粘性又是全局的正则表达式的行为与粘性和非全局正则表达式的行为相同。因为 test()
是 exec()
的简单包装器,所以 test()
也将忽略全局标志并执行粘性匹配。但是,由于许多其他方法对全局正则表达式的行为进行了特殊处理,因此通常情况下,全局标志与粘性标志正交。
String.prototype.matchAll()
(调用RegExp.prototype[Symbol.matchAll]()
):y
、g
和gy
都是不同的。- 对于
y
正则表达式:matchAll()
抛出异常;[Symbol.matchAll]()
恰好一次产生exec()
结果,而不更新正则表达式的lastIndex
。 - 对于
g
或gy
正则表达式:返回一个迭代器,该迭代器产生一系列exec()
结果。
- 对于
String.prototype.match()
(调用RegExp.prototype[Symbol.match]()
):y
、g
和gy
都是不同的。- 对于
y
正则表达式:返回exec()
结果并更新正则表达式的lastIndex
。 - 对于
g
或gy
正则表达式:返回所有exec()
结果的数组。
- 对于
String.prototype.search()
(调用RegExp.prototype[Symbol.search]()
):g
标志始终无关紧要。- 对于
y
或gy
正则表达式:始终返回0
(如果字符串的开头匹配)或-1
(如果开头不匹配),在退出时不更新正则表达式的lastIndex
。 - 对于
g
正则表达式:返回字符串中第一个匹配项的索引,如果未找到匹配项则返回-1
。
- 对于
String.prototype.split()
(调用RegExp.prototype[Symbol.split]()
):y
、g
和gy
的行为都相同。String.prototype.replace()
(调用RegExp.prototype[Symbol.replace]()
):y
、g
和gy
都是不同的。- 对于
y
正则表达式:在当前lastIndex
处替换一次并更新lastIndex
。 - 对于
g
和gy
正则表达式:替换exec()
匹配的所有出现。
- 对于
String.prototype.replaceAll()
(调用RegExp.prototype[Symbol.replace]()
):y
、g
和gy
都是不同的。- 对于
y
正则表达式:replaceAll()
抛出异常。 - 对于
g
和gy
正则表达式:替换exec()
匹配的所有出现。
- 对于
示例
使用带有粘性标志的正则表达式
js
const str = "#foo#";
const regex = /foo/y;
regex.lastIndex = 1;
regex.test(str); // true
regex.lastIndex = 5;
regex.test(str); // false (lastIndex is taken into account with sticky flag)
regex.lastIndex; // 0 (reset after match failure)
锚定粘性标志
在多个版本中,Firefox 的 SpiderMonkey 引擎在 ^
断言和粘性标志方面存在 错误,该错误允许以 ^
断言开头并使用粘性标志的表达式在不应该匹配时匹配。该错误是在 Firefox 3.6(具有粘性标志但没有错误)之后的一段时间内引入的,并在 2015 年修复。也许是因为这个错误,规范 特别指出 了以下事实:
即使
y
标志与模式一起使用,^
也始终只匹配 输入 的开头,或者(如果 rer.[[Multiline]] 为true
)匹配行的开头。
正确行为的示例
js
const regex = /^foo/y;
regex.lastIndex = 2;
regex.test("..foo"); // false - index 2 is not the beginning of the string
const regex2 = /^foo/my;
regex2.lastIndex = 2;
regex2.test("..foo"); // false - index 2 is not the beginning of the string or line
regex2.lastIndex = 2;
regex2.test(".\nfoo"); // true - index 2 is the beginning of a line
规范
规范 |
---|
ECMAScript 语言规范 # sec-get-regexp.prototype.sticky |
浏览器兼容性
BCD 表格仅在启用 JavaScript 的浏览器中加载。