{"checkedAt":"2026-10-17T13:05:49.731Z","node":"v26.12.0","v8":"14.6.202.34-node.39","lint":[{"name":"nested","code":"const r = /^(a+)+$/; r.test(input);","diagnostics":[{"ruleId":"regexp/no-super-linear-backtracking","line":1,"column":14,"endLine":1,"endColumn":16}]},{"name":"overlap","code":"const r = /^(a|aa)+$/; r.test(input);","diagnostics":[]},{"name":"move","code":"const r = /a+$/; r.test(input);","diagnostics":[{"ruleId":"regexp/no-super-linear-move","line":1,"column":12,"endLine":1,"endColumn":14}]},{"name":"disjoint","code":"const r = /^(a|b)+$/; r.test(input);","diagnostics":[]},{"name":"delimited","code":"const r = /^(ab+)+$/; r.test(input);","diagnostics":[]},{"name":"flat","code":"const r = /^a+$/; r.test(input);","diagnostics":[]},{"name":"constructor","code":"new RegExp('^(a+)+$').test(input);","diagnostics":[{"ruleId":"regexp/no-super-linear-backtracking","line":1,"column":15,"endLine":1,"endColumn":17}]},{"name":"dynamic","code":"new RegExp(input).test(text);","diagnostics":[]},{"name":"fragment","code":"const fragment = /(?:a+)+/; export { fragment };","diagnostics":[]}],"engines":[{"args":[],"results":[{"pattern":"a+","flags":"l","accepted":false,"error":"SyntaxError"},{"pattern":"(?<=a)b","flags":"l","accepted":false,"error":"SyntaxError"},{"pattern":"(?=a)a","flags":"l","accepted":false,"error":"SyntaxError"},{"pattern":"(?<=a)b","flags":"lg","accepted":false,"error":"SyntaxError"},{"pattern":"a+","flags":"lu","accepted":false,"error":"SyntaxError"},{"pattern":"(a)\\1","flags":"l","accepted":false,"error":"SyntaxError"}]},{"args":["--enable-experimental-regexp-engine"],"results":[{"pattern":"a+","flags":"l","accepted":true,"result":true},{"pattern":"(?<=a)b","flags":"l","accepted":true,"result":true},{"pattern":"(?=a)a","flags":"l","accepted":false,"error":"SyntaxError"},{"pattern":"(?<=a)b","flags":"lg","accepted":false,"error":"SyntaxError"},{"pattern":"a+","flags":"lu","accepted":false,"error":"SyntaxError"},{"pattern":"(a)\\1","flags":"l","accepted":false,"error":"SyntaxError"}]},{"args":["--enable-experimental-regexp-engine","--experimental-regexp-engine-capture-group-opt"],"results":[{"pattern":"a+","flags":"l","accepted":true,"result":true},{"pattern":"(?<=a)b","flags":"l","accepted":true,"result":true},{"pattern":"(?=a)a","flags":"l","accepted":true,"result":true},{"pattern":"(?<=a)b","flags":"lg","accepted":false,"error":"SyntaxError"},{"pattern":"a+","flags":"lu","accepted":false,"error":"SyntaxError"},{"pattern":"(a)\\1","flags":"l","accepted":false,"error":"SyntaxError"}]}],"timings":[{"n":12,"args":[],"result":false,"ms":0.2480000000000011},{"n":12,"args":["--enable-experimental-regexp-engine-on-excessive-backtracks"],"result":false,"ms":0.31259999999999977},{"n":18,"args":[],"result":false,"ms":11.962},{"n":18,"args":["--enable-experimental-regexp-engine-on-excessive-backtracks"],"result":false,"ms":1.5244999999999997},{"n":24,"args":[],"result":false,"ms":757.5831000000001},{"n":24,"args":["--enable-experimental-regexp-engine-on-excessive-backtracks"],"result":false,"ms":1.6280999999999999},{"n":32,"args":[],"status":"timeout"},{"n":32,"args":["--enable-experimental-regexp-engine-on-excessive-backtracks"],"result":false,"ms":1.497399999999999}],"lookbehinds":[{"pattern":"(?<=foo)bar","flag":512,"result":true},{"pattern":"(?<=(foo))bar","error":"RE2JSSyntaxException","message":"error parsing regexp: invalid capture in lookbehind: `(?<=(foo))bar`"},{"pattern":"(?=foo)foo","error":"RE2JSSyntaxException","message":"error parsing regexp: invalid or unsupported Perl syntax: `(?=`"}],"metadata":{"re2js-release":{"tag":"2.8.6","date":"2026-07-05T18:46:46Z"},"v8-commit":{"sha":"07dbe6b53fa73541361282f63d702e5aee9f8a92","date":"2026-10-17T07:05:42Z"},"webkit-commit":{"sha":"75bd0aeec27cf4343b8bc7f90de55a6ca8c76d24","date":"2026-10-17T12:32:25Z"},"sonar-commit":{"sha":"5e80d9927864b072f5a728734f4095d7ea1ccbd6","date":"2026-10-16T13:18:06Z"}},"lintRules":["regexp/no-super-linear-backtracking","regexp/no-super-linear-move","regexp/no-dupe-disjunctions"],"lintNote":"额外启用第三条规则的重复验证；配套 copy 配置启用前两条。六个确定样例由配置自检另行验证。","expandedExamples":{"checkedAt":"2026-10-17T13:26:14.922Z","escapedKeyword":{"input":"a+b","output":"\\x61\\+b"},"re2jsMatching":{"nativeTest":true,"find":true,"matches":false},"booleanRewrite":{"alphabet":["0","a","f","!","\n","A"],"maxLength":5,"samples":9331,"equivalent":true}},"reviewExamples":{"checkedAt":"2026-10-17T16:40:53.258Z","node":"v26.12.0","v8":"14.6.202.34-node.39","cases":[{"input":"foo","expected":true,"bounded":true,"slug":true,"ambiguousSlug":true,"characterOnly":true},{"input":"foo-bar","expected":true,"bounded":true,"slug":true,"ambiguousSlug":true,"characterOnly":true},{"input":"foo-bar-baz","expected":true,"bounded":true,"slug":true,"ambiguousSlug":true,"characterOnly":true},{"input":"","expected":false,"bounded":false,"slug":false,"ambiguousSlug":false,"characterOnly":false},{"input":"-foo","expected":false,"bounded":false,"slug":false,"ambiguousSlug":false,"characterOnly":true},{"input":"foo-","expected":false,"bounded":false,"slug":false,"ambiguousSlug":false,"characterOnly":true},{"input":"foo--bar","expected":false,"bounded":false,"slug":false,"ambiguousSlug":false,"characterOnly":true},{"input":"Foo","expected":false,"bounded":false,"slug":false,"ambiguousSlug":false,"characterOnly":false},{"input":"foo\n","expected":false,"bounded":false,"slug":false,"ambiguousSlug":false,"characterOnly":false},{"input":"aaaa!","expected":false,"bounded":false,"slug":false,"ambiguousSlug":false,"characterOnly":false},{"input":"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","expected":true,"bounded":true,"slug":true,"ambiguousSlug":true,"characterOnly":true},{"input":"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","expected":false,"bounded":false,"slug":true,"ambiguousSlug":true,"characterOnly":true}],"exhaustiveCheck":{"alphabet":["a","b","-","!","\n"],"maxLength":7,"tested":97656,"oracle":"按横线拆分，所有分段非空且仅由小写 ASCII 字母构成","scope":"有限枚举核对接受集合，不证明复杂度或所有长度的等价性"},"lint":[{"name":"slug","pattern":"/^[a-z]+(?:-[a-z]+)*$/","diagnostics":[]},{"name":"ambiguousSlug","pattern":"/^[a-z]+(?:-?[a-z]+)*$/","diagnostics":[{"ruleId":"regexp/no-super-linear-backtracking","message":"The quantifier '[a-z]+' can exchange characters with '(?:-?[a-z]+)*'. Using any string accepted by /[a-z]+/, this can be exploited to cause at least polynomial backtracking."},{"ruleId":"regexp/no-super-linear-backtracking","message":"The quantifier '[a-z]+' can exchange characters with '[a-z]+'. Using any string accepted by /[a-z]+/, this can be exploited to cause at least polynomial backtracking."},{"ruleId":"regexp/no-super-linear-backtracking","message":"This quantifier can reach itself via the loop '(?:-?[a-z]+)*'. Using any string accepted by /[a-z]+/, this can be exploited to cause at least polynomial backtracking. This is going to cause exponential backtracking resulting in exponential worst-case runtime behavior."}]},{"name":"characterOnly","pattern":"/^[a-z-]+$/","diagnostics":[]},{"name":"hex","pattern":"/^[0-9a-f]+$/","diagnostics":[]},{"name":"ambiguousHex","pattern":"/^([0-9a-f]+)+$/","diagnostics":[{"ruleId":"regexp/no-super-linear-backtracking","message":"This quantifier can reach itself via the loop '([0-9a-f]+)+'. Using any string accepted by /[\\da-f]+/, this can be exploited to cause at least polynomial backtracking. This is going to cause exponential backtracking resulting in exponential worst-case runtime behavior."}]}]},"ruleExplanations":{"checkedAt":"2026-10-17T17:13:31.942Z","eslint":"10.12.0","plugin":"3.3.1","method":"仅静态分析，每条规则独立运行；不执行危险匹配","result":[{"name":"backtracking-certain","rule":"no-super-linear-backtracking","options":{"report":"certain"},"cases":[{"name":"self","code":"const pattern=/^(a+)+$/; pattern.test(input);","diagnostics":[{"ruleId":"regexp/no-super-linear-backtracking","messageId":"self","message":"This quantifier can reach itself via the loop '(a+)+'. Using any string accepted by /a+/, this can be exploited to cause at least polynomial backtracking. This is going to cause exponential backtracking resulting in exponential worst-case runtime behavior.","line":1,"column":18,"endLine":1,"endColumn":20}]},{"name":"trade","code":"const pattern=/^a+a+$/; pattern.test(input);","diagnostics":[{"ruleId":"regexp/no-super-linear-backtracking","messageId":"trade","message":"The quantifier 'a+' can exchange characters with 'a+'. Using any string accepted by /a+/, this can be exploited to cause at least polynomial backtracking.","line":1,"column":17,"endLine":1,"endColumn":21}]},{"name":"move","code":"const pattern=/a+$/; pattern.test(input);","diagnostics":[]},{"name":"flat","code":"const pattern=/^a+$/; pattern.test(input);","diagnostics":[]},{"name":"disjoint","code":"const pattern=/^(a|b)+$/; pattern.test(input);","diagnostics":[]},{"name":"boundary","code":"const pattern=/^(ab+)+$/; pattern.test(input);","diagnostics":[]},{"name":"overlap","code":"const pattern=/^(a|aa)+$/; pattern.test(input);","diagnostics":[]},{"name":"unbounded-success","code":"const pattern=/(?:a+)+/; pattern.test(input);","diagnostics":[]},{"name":"sticky","code":"const pattern=/a+$/y; pattern.test(input);","diagnostics":[]},{"name":"hex","code":"const pattern=/^([0-9a-f]+)+$/; pattern.test(input);","diagnostics":[{"ruleId":"regexp/no-super-linear-backtracking","messageId":"self","message":"This quantifier can reach itself via the loop '([0-9a-f]+)+'. Using any string accepted by /[\\da-f]+/, this can be exploited to cause at least polynomial backtracking. This is going to cause exponential backtracking resulting in exponential worst-case runtime behavior.","line":1,"column":18,"endLine":1,"endColumn":27}]},{"name":"slug-optional","code":"const pattern=/^[a-z]+(?:-?[a-z]+)*$/; pattern.test(input);","diagnostics":[{"ruleId":"regexp/no-super-linear-backtracking","messageId":"trade","message":"The quantifier '[a-z]+' can exchange characters with '(?:-?[a-z]+)*'. Using any string accepted by /[a-z]+/, this can be exploited to cause at least polynomial backtracking.","line":1,"column":17,"endLine":1,"endColumn":36},{"ruleId":"regexp/no-super-linear-backtracking","messageId":"trade","message":"The quantifier '[a-z]+' can exchange characters with '[a-z]+'. Using any string accepted by /[a-z]+/, this can be exploited to cause at least polynomial backtracking.","line":1,"column":17,"endLine":1,"endColumn":34},{"ruleId":"regexp/no-super-linear-backtracking","messageId":"self","message":"This quantifier can reach itself via the loop '(?:-?[a-z]+)*'. Using any string accepted by /[a-z]+/, this can be exploited to cause at least polynomial backtracking. This is going to cause exponential backtracking resulting in exponential worst-case runtime behavior.","line":1,"column":28,"endLine":1,"endColumn":34}]},{"name":"slug-delimited","code":"const pattern=/^[a-z]+(?:-[a-z]+)*$/; pattern.test(input);","diagnostics":[]},{"name":"slug-characters","code":"const pattern=/^[a-z-]+$/; pattern.test(input);","diagnostics":[]},{"name":"fragment-success","code":"export const part = /(?:a+)+/.source;","diagnostics":[]},{"name":"fragment-move","code":"export const part = /a+$/.source;","diagnostics":[]},{"name":"dynamic","code":"new RegExp(input).test(text);","diagnostics":[]}]},{"name":"backtracking-potential","rule":"no-super-linear-backtracking","options":{"report":"potential"},"cases":[{"name":"self","code":"const pattern=/^(a+)+$/; pattern.test(input);","diagnostics":[{"ruleId":"regexp/no-super-linear-backtracking","messageId":"self","message":"This quantifier can reach itself via the loop '(a+)+'. Using any string accepted by /a+/, this can be exploited to cause at least polynomial backtracking. This is going to cause exponential backtracking resulting in exponential worst-case runtime behavior.","line":1,"column":18,"endLine":1,"endColumn":20}]},{"name":"trade","code":"const pattern=/^a+a+$/; pattern.test(input);","diagnostics":[{"ruleId":"regexp/no-super-linear-backtracking","messageId":"trade","message":"The quantifier 'a+' can exchange characters with 'a+'. Using any string accepted by /a+/, this can be exploited to cause at least polynomial backtracking.","line":1,"column":17,"endLine":1,"endColumn":21}]},{"name":"move","code":"const pattern=/a+$/; pattern.test(input);","diagnostics":[]},{"name":"flat","code":"const pattern=/^a+$/; pattern.test(input);","diagnostics":[]},{"name":"disjoint","code":"const pattern=/^(a|b)+$/; pattern.test(input);","diagnostics":[]},{"name":"boundary","code":"const pattern=/^(ab+)+$/; pattern.test(input);","diagnostics":[]},{"name":"overlap","code":"const pattern=/^(a|aa)+$/; pattern.test(input);","diagnostics":[]},{"name":"unbounded-success","code":"const pattern=/(?:a+)+/; pattern.test(input);","diagnostics":[]},{"name":"sticky","code":"const pattern=/a+$/y; pattern.test(input);","diagnostics":[]},{"name":"hex","code":"const pattern=/^([0-9a-f]+)+$/; pattern.test(input);","diagnostics":[{"ruleId":"regexp/no-super-linear-backtracking","messageId":"self","message":"This quantifier can reach itself via the loop '([0-9a-f]+)+'. Using any string accepted by /[\\da-f]+/, this can be exploited to cause at least polynomial backtracking. This is going to cause exponential backtracking resulting in exponential worst-case runtime behavior.","line":1,"column":18,"endLine":1,"endColumn":27}]},{"name":"slug-optional","code":"const pattern=/^[a-z]+(?:-?[a-z]+)*$/; pattern.test(input);","diagnostics":[{"ruleId":"regexp/no-super-linear-backtracking","messageId":"trade","message":"The quantifier '[a-z]+' can exchange characters with '(?:-?[a-z]+)*'. Using any string accepted by /[a-z]+/, this can be exploited to cause at least polynomial backtracking.","line":1,"column":17,"endLine":1,"endColumn":36},{"ruleId":"regexp/no-super-linear-backtracking","messageId":"trade","message":"The quantifier '[a-z]+' can exchange characters with '[a-z]+'. Using any string accepted by /[a-z]+/, this can be exploited to cause at least polynomial backtracking.","line":1,"column":17,"endLine":1,"endColumn":34},{"ruleId":"regexp/no-super-linear-backtracking","messageId":"self","message":"This quantifier can reach itself via the loop '(?:-?[a-z]+)*'. Using any string accepted by /[a-z]+/, this can be exploited to cause at least polynomial backtracking. This is going to cause exponential backtracking resulting in exponential worst-case runtime behavior.","line":1,"column":28,"endLine":1,"endColumn":34}]},{"name":"slug-delimited","code":"const pattern=/^[a-z]+(?:-[a-z]+)*$/; pattern.test(input);","diagnostics":[]},{"name":"slug-characters","code":"const pattern=/^[a-z-]+$/; pattern.test(input);","diagnostics":[]},{"name":"fragment-success","code":"export const part = /(?:a+)+/.source;","diagnostics":[{"ruleId":"regexp/no-super-linear-backtracking","messageId":"self","message":"This quantifier can reach itself via the loop '(?:a+)+'. Using any string accepted by /a+/, this can be exploited to cause at least polynomial backtracking. This is going to cause exponential backtracking resulting in exponential worst-case runtime behavior.","line":1,"column":25,"endLine":1,"endColumn":27}]},{"name":"fragment-move","code":"export const part = /a+$/.source;","diagnostics":[]},{"name":"dynamic","code":"new RegExp(input).test(text);","diagnostics":[]}]},{"name":"move-default","rule":"no-super-linear-move","options":{},"cases":[{"name":"self","code":"const pattern=/^(a+)+$/; pattern.test(input);","diagnostics":[]},{"name":"trade","code":"const pattern=/^a+a+$/; pattern.test(input);","diagnostics":[]},{"name":"move","code":"const pattern=/a+$/; pattern.test(input);","diagnostics":[{"ruleId":"regexp/no-super-linear-move","messageId":"unexpected","message":"Any attack string /a+/ plus some rejecting suffix will cause quadratic runtime because of this quantifier.","line":1,"column":16,"endLine":1,"endColumn":18}]},{"name":"flat","code":"const pattern=/^a+$/; pattern.test(input);","diagnostics":[]},{"name":"disjoint","code":"const pattern=/^(a|b)+$/; pattern.test(input);","diagnostics":[]},{"name":"boundary","code":"const pattern=/^(ab+)+$/; pattern.test(input);","diagnostics":[]},{"name":"overlap","code":"const pattern=/^(a|aa)+$/; pattern.test(input);","diagnostics":[]},{"name":"unbounded-success","code":"const pattern=/(?:a+)+/; pattern.test(input);","diagnostics":[]},{"name":"sticky","code":"const pattern=/a+$/y; pattern.test(input);","diagnostics":[]},{"name":"hex","code":"const pattern=/^([0-9a-f]+)+$/; pattern.test(input);","diagnostics":[]},{"name":"slug-optional","code":"const pattern=/^[a-z]+(?:-?[a-z]+)*$/; pattern.test(input);","diagnostics":[]},{"name":"slug-delimited","code":"const pattern=/^[a-z]+(?:-[a-z]+)*$/; pattern.test(input);","diagnostics":[]},{"name":"slug-characters","code":"const pattern=/^[a-z-]+$/; pattern.test(input);","diagnostics":[]},{"name":"fragment-success","code":"export const part = /(?:a+)+/.source;","diagnostics":[]},{"name":"fragment-move","code":"export const part = /a+$/.source;","diagnostics":[]},{"name":"dynamic","code":"new RegExp(input).test(text);","diagnostics":[]}]},{"name":"move-check-sticky","rule":"no-super-linear-move","options":{"ignoreSticky":false},"cases":[{"name":"self","code":"const pattern=/^(a+)+$/; pattern.test(input);","diagnostics":[]},{"name":"trade","code":"const pattern=/^a+a+$/; pattern.test(input);","diagnostics":[]},{"name":"move","code":"const pattern=/a+$/; pattern.test(input);","diagnostics":[{"ruleId":"regexp/no-super-linear-move","messageId":"unexpected","message":"Any attack string /a+/ plus some rejecting suffix will cause quadratic runtime because of this quantifier.","line":1,"column":16,"endLine":1,"endColumn":18}]},{"name":"flat","code":"const pattern=/^a+$/; pattern.test(input);","diagnostics":[]},{"name":"disjoint","code":"const pattern=/^(a|b)+$/; pattern.test(input);","diagnostics":[]},{"name":"boundary","code":"const pattern=/^(ab+)+$/; pattern.test(input);","diagnostics":[]},{"name":"overlap","code":"const pattern=/^(a|aa)+$/; pattern.test(input);","diagnostics":[]},{"name":"unbounded-success","code":"const pattern=/(?:a+)+/; pattern.test(input);","diagnostics":[]},{"name":"sticky","code":"const pattern=/a+$/y; pattern.test(input);","diagnostics":[{"ruleId":"regexp/no-super-linear-move","messageId":"unexpected","message":"Any attack string /a+/ plus some rejecting suffix will cause quadratic runtime because of this quantifier.","line":1,"column":16,"endLine":1,"endColumn":18}]},{"name":"hex","code":"const pattern=/^([0-9a-f]+)+$/; pattern.test(input);","diagnostics":[]},{"name":"slug-optional","code":"const pattern=/^[a-z]+(?:-?[a-z]+)*$/; pattern.test(input);","diagnostics":[]},{"name":"slug-delimited","code":"const pattern=/^[a-z]+(?:-[a-z]+)*$/; pattern.test(input);","diagnostics":[]},{"name":"slug-characters","code":"const pattern=/^[a-z-]+$/; pattern.test(input);","diagnostics":[]},{"name":"fragment-success","code":"export const part = /(?:a+)+/.source;","diagnostics":[]},{"name":"fragment-move","code":"export const part = /a+$/.source;","diagnostics":[]},{"name":"dynamic","code":"new RegExp(input).test(text);","diagnostics":[]}]},{"name":"move-check-partial","rule":"no-super-linear-move","options":{"ignorePartial":false},"cases":[{"name":"self","code":"const pattern=/^(a+)+$/; pattern.test(input);","diagnostics":[]},{"name":"trade","code":"const pattern=/^a+a+$/; pattern.test(input);","diagnostics":[]},{"name":"move","code":"const pattern=/a+$/; pattern.test(input);","diagnostics":[{"ruleId":"regexp/no-super-linear-move","messageId":"unexpected","message":"Any attack string /a+/ plus some rejecting suffix will cause quadratic runtime because of this quantifier.","line":1,"column":16,"endLine":1,"endColumn":18}]},{"name":"flat","code":"const pattern=/^a+$/; pattern.test(input);","diagnostics":[]},{"name":"disjoint","code":"const pattern=/^(a|b)+$/; pattern.test(input);","diagnostics":[]},{"name":"boundary","code":"const pattern=/^(ab+)+$/; pattern.test(input);","diagnostics":[]},{"name":"overlap","code":"const pattern=/^(a|aa)+$/; pattern.test(input);","diagnostics":[]},{"name":"unbounded-success","code":"const pattern=/(?:a+)+/; pattern.test(input);","diagnostics":[]},{"name":"sticky","code":"const pattern=/a+$/y; pattern.test(input);","diagnostics":[]},{"name":"hex","code":"const pattern=/^([0-9a-f]+)+$/; pattern.test(input);","diagnostics":[]},{"name":"slug-optional","code":"const pattern=/^[a-z]+(?:-?[a-z]+)*$/; pattern.test(input);","diagnostics":[]},{"name":"slug-delimited","code":"const pattern=/^[a-z]+(?:-[a-z]+)*$/; pattern.test(input);","diagnostics":[]},{"name":"slug-characters","code":"const pattern=/^[a-z-]+$/; pattern.test(input);","diagnostics":[]},{"name":"fragment-success","code":"export const part = /(?:a+)+/.source;","diagnostics":[]},{"name":"fragment-move","code":"export const part = /a+$/.source;","diagnostics":[{"ruleId":"regexp/no-super-linear-move","messageId":"unexpected","message":"Any attack string /a+/ plus some rejecting suffix will cause quadratic runtime because of this quantifier.","line":1,"column":22,"endLine":1,"endColumn":24}]},{"name":"dynamic","code":"new RegExp(input).test(text);","diagnostics":[]}]}]}}