试一试
const str = "table football";
const regex = /foo/y;
regex.lastIndex = 6;
console.log(regex.sticky);
// Expected output: true
console.log(regex.test(str));
// Expected output: true
console.log(regex.test(str));
// Expected output: false
描述
如果使用了 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 引擎在 ^ 断言和粘滞标志方面存在 一个 bug,该 bug 允许以 ^ 断言开头并使用粘滞标志的表达式在不应匹配时进行匹配。此 bug 在 Firefox 3.6(具有粘滞标志但无 bug)之后一段时间引入,并于 2015 年修复。也许是由于这个 bug,规范 专门指出:
即使在使用
y标志的模式中,^也始终只匹配输入的开头,或者(如果 rer.[[Multiline]] 为true)匹配行的开头。
正确行为示例
js
const regex1 = /^foo/y;
regex1.lastIndex = 2;
regex1.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® 2026 语言规范 # sec-get-regexp.prototype.sticky |
浏览器兼容性
加载中…