eslint no-div-regex
labelled safe
Analysis Nemotron 3 Super
Flags regex literals starting with '/=' to avoid confusion with the division-assignment operator.
Fix: Wraps the '=' character immediately following the opening '/' in a character class, transforming '/=...' into '/[=]...'
8 hazards
- If the regex contains an unescaped ']' before the '=', wrapping '=' in '[=]' alters the character class meaning and may cause incorrect matching or a syntax error.
- If the regex uses a character class that already contains '=' (e.g., '/[=]/'), the fix produces '/[[=]]/' which nests a character class and is invalid syntax.
- If the regex has a flag like 'u' (unicode) and the '=' is part of a Unicode escape sequence (e.g., '/=\u003D/'), the fix breaks the escape by inserting '[=]' before it, changing the matched character.
- If the regex is used in a dynamic context like new RegExp(String(raw)), the source alteration changes the pattern and thus runtime behavior.
- If the regex literal is immediately followed by a comment on the same line without a newline (e.g., '/=foo/#fix'), moving the '=' into a class may disrupt comment parsing if the fixer does not preserve whitespace exactly.
- If the regex is part of a larger expression where operator precedence matters (e.g., 'x += /=foo/ * y'), though unlikely due to prior '/' token, the fix does not alter precedence but the change in literal value could affect results.
- If the regex contains a trailing unescaped '/' before a flag (e.g., '/=/[/]'), the fix does not interfere, but if the original had '/=[]/', the fix yields '/[=][]/' which is valid but may not be intended if the author meant an empty class.
- If the regex is inside a template literal or string that is later evaluated (e.g., `regExpString = "/=foo/"; new RegExp(regExpString)`), the fix does not apply because it's not a literal, so no hazard—but if mistakenly applied via string manipulation, it would corrupt the pattern.
Programs
| id | result | title | hazard |
|---|---|---|---|
| r1-p001 | fix ok | Name collision via shadowing | name collisions across scopes after a move (shadowing) |
| r1-p002 | fix ok | Operator precedence interaction | If the regex is part of a larger expression where operator precedence matters |
| r1-p003 | fix ok | Arguments and parameter interactions | arguments object, function.length, default parameters, rest parameters |
| r1-p004 | fix ok | ASI and semicolon-less leading paren/bracket | ASI and semicolon-less code, leading ( or [ on the next line |
| r1-p005 | fix ok prediction off | Strict vs sloppy mode semantics | strict vs sloppy mode semantics |
| r1-p006 | fix ok | Class fields and private names interaction | class fields, static blocks, private names, super calls |
| r1-p007 | fix ok | Inline comment disruption | If the regex literal is immediately followed by a comment on the same line without a newline |
| r1-p008 | fix ok | This binding in arrows vs functions | this binding: arrow vs function, methods extracted from objects, call/apply/bind |
| r2-p001 | fix ok | Label break continue with labeled block | label/break/continue control flow, finally blocks, early returns in nested blocks |
| r2-p002 | fix ok | Regex in arithmetic expression under precedence | If the regex is part of a larger expression where operator precedence matters (e.g., 'x += /=foo/ * y') |
| r2-p003 | fix ok | Function declaration inside switch case | function declarations inside blocks, switch cases, labeled statements |
| r2-p004 | fix ok | Regex with unicode flag and lastIndex mutation | regular expressions: escapes, unicode flag, lastIndex with the g flag |
| r2-p005 | fix ok | Dynamic RegExp construction from stringified regex | If the regex is used in a dynamic context like new RegExp(String(raw)), the source alteration changes the pattern and thus runtime behavior. |
| r2-p006 | fix ok | Unicode escape broken by fix in unicode flag regex | If the regex has a flag like 'u' (unicode) and the '=' is part of a Unicode escape sequence (e.g., '/=\u003D/'), the fix breaks the escape by inserting '[=]' before it, changing the matched character. |
| r2-p007 | fix ok | Strict mode regex usage | strict vs sloppy mode semantics |
| r2-p008 | fix ok | This binding in arrow vs function with regex | this binding: arrow vs function, methods extracted from objects, call/apply/bind |
Sources
r1-p001 · Name collision via shadowing
1function f() {
2 var foo = 1;
3 { let foo = 2; console.log(/=/.test(foo)); }
4}
5f();
--- orig.js 2026-10-22 14:15:11.723671773 -0400 +++ fixed.js 2026-10-22 14:15:15.194762776 -0400 @@ -1,5 +1,5 @@ function f() { var foo = 1; - { let foo = 2; console.log(/=/.test(foo)); } + { let foo = 2; console.log(/[=]/.test(foo)); } } f();
false
r1-p002 · Operator precedence interaction
1let x = 1;
2x *= /=a/.test('ba') + 2;
3console.log(x);
--- orig.js 2026-10-22 14:15:11.724671798 -0400 +++ fixed.js 2026-10-22 14:15:15.166762038 -0400 @@ -1,3 +1,3 @@ let x = 1; -x *= /=a/.test('ba') + 2; +x *= /[=]a/.test('ba') + 2; console.log(x);
2
r1-p003 · Arguments and parameter interactions
1function g(a, b = /=/i.test('x'), ...r) {
2 console.log(arguments.length, b, r.length);
3}
4g(1);
--- orig.js 2026-10-22 14:15:11.725671825 -0400 +++ fixed.js 2026-10-22 14:15:14.754751188 -0400 @@ -1,4 +1,4 @@ -function g(a, b = /=/i.test('x'), ...r) { +function g(a, b = /[=]/i.test('x'), ...r) { console.log(arguments.length, b, r.length); } g(1);
1 false 0
r1-p004 · ASI and semicolon-less leading paren/bracket
1let y
2(/=/.test('x') ? 1 : 0)
3console.log(y)
--- orig.js 2026-10-22 14:15:11.726671850 -0400 +++ fixed.js 2026-10-22 14:15:15.243764069 -0400 @@ -1,3 +1,3 @@ let y -(/=/.test('x') ? 1 : 0) +(/[=]/.test('x') ? 1 : 0) console.log(y)
undefined
r1-p005 · Strict vs sloppy mode semantics
1"use strict";
2(function(){ return !/=/.test(''); })();
--- orig.js 2026-10-22 14:15:11.726671850 -0400 +++ fixed.js 2026-10-22 14:15:14.031732173 -0400 @@ -1,2 +1,2 @@ "use strict"; -(function(){ return !/=/.test(''); })(); +(function(){ return !/[=]/.test(''); })();
r1-p006 · Class fields and private names interaction
1class C {
2 static rx = /=/;
3 m() { console.log(C.rx.test('x'));
4 }
5}
6new C().m();
--- orig.js 2026-10-22 14:15:11.727671877 -0400 +++ fixed.js 2026-10-22 14:15:14.021731910 -0400 @@ -1,5 +1,5 @@ class C { - static rx = /=/; + static rx = /[=]/; m() { console.log(C.rx.test('x')); } }
false
r1-p007 · Inline comment disruption
1let z = /=/i; // flag test
2console.log(z.test('x'));
--- orig.js 2026-10-22 14:15:15.180762407 -0400 +++ fixed.js 2026-10-22 14:15:18.584852572 -0400 @@ -1,2 +1,2 @@ -let z = /=/i; // flag test +let z = /[=]/i; // flag test console.log(z.test('x'));
false
r1-p008 · This binding in arrows vs functions
1const obj = {
2 get rx() { return /=/; },
3 getArrow: () => /=/,
4 getFn: function() { return /=;/ }
5};
6console.log(obj.getArrow().test('x'), obj.getFn().test('x'));
--- orig.js 2026-10-22 14:15:16.433795494 -0400 +++ fixed.js 2026-10-22 14:15:19.905887797 -0400 @@ -1,6 +1,6 @@ const obj = { - get rx() { return /=/; }, - getArrow: () => /=/, - getFn: function() { return /=;/ } + get rx() { return /[=]/; }, + getArrow: () => /[=]/, + getFn: function() { return /[=];/ } }; console.log(obj.getArrow().test('x'), obj.getFn().test('x'));
false false
r2-p001 · Label break continue with labeled block
1outer: {
2 let result = '';
3 inner: {
4 if (/=a/.test('xa')) {
5 break outer;
6 }
7 result += 'not broken';
8 }
9 result += ' after inner';
10}
11console.log(result);
--- orig.js 2026-10-22 14:15:28.820129009 -0400 +++ fixed.js 2026-10-22 14:15:31.684207772 -0400 @@ -1,7 +1,7 @@ outer: { let result = ''; inner: { - if (/=a/.test('xa')) { + if (/[=]a/.test('xa')) { break outer; } result += 'not broken';
r2-p002 · Regex in arithmetic expression under precedence
1let x = 1;
2const y = 2;
3x += /=2/.test('x2') * y;
4console.log(x);
--- orig.js 2026-10-22 14:15:28.821129036 -0400 +++ fixed.js 2026-10-22 14:15:31.693208021 -0400 @@ -1,4 +1,4 @@ let x = 1; const y = 2; -x += /=2/.test('x2') * y; +x += /[=]2/.test('x2') * y; console.log(x);
1
r2-p003 · Function declaration inside switch case
1switch (1) {
2 case 1:
3 function check() {
4 return /=b/.test('ab');
5 }
6 console.log(check());
7 break;
8}
--- orig.js 2026-10-22 14:15:28.822129063 -0400 +++ fixed.js 2026-10-22 14:15:32.372226783 -0400 @@ -1,7 +1,7 @@ switch (1) { case 1: function check() { - return /=b/.test('ab'); + return /[=]b/.test('ab'); } console.log(check()); break;
false
r2-p004 · Regex with unicode flag and lastIndex mutation
1const re = /=🌟/gu;
2re.lastIndex = 0;
3console.log(re.test('a🌟b'));
4re.lastIndex = 0;
5console.log(re.exec('x🌟y'));
--- orig.js 2026-10-22 14:15:28.823129091 -0400 +++ fixed.js 2026-10-22 14:15:31.653206917 -0400 @@ -1,4 +1,4 @@ -const re = /=🌟/gu; +const re = /[=]🌟/gu; re.lastIndex = 0; console.log(re.test('a🌟b')); re.lastIndex = 0;
false null
r2-p005 · Dynamic RegExp construction from stringified regex
1const raw = /=test/;
2const re1 = new RegExp(String(raw));
3console.log(re1.test('xtest'));
4const re2 = /=[=]test/;
5console.log(re2.test('xtest'));
--- orig.js 2026-10-22 14:15:28.824129118 -0400 +++ fixed.js 2026-10-22 14:15:32.304224902 -0400 @@ -1,5 +1,5 @@ -const raw = /=test/; +const raw = /[=]test/; const re1 = new RegExp(String(raw)); console.log(re1.test('xtest')); -const re2 = /=[=]test/; +const re2 = /[=][=]test/; console.log(re2.test('xtest'));
false false
r2-p006 · Unicode escape broken by fix in unicode flag regex
1const re = /=\u003D/u;
2console.log(re.test('=='));
3console.log('Match:', re.test('='));
--- orig.js 2026-10-22 14:15:28.825129146 -0400 +++ fixed.js 2026-10-22 14:15:31.089191355 -0400 @@ -1,3 +1,3 @@ -const re = /=\u003D/u; +const re = /[=]\u003D/u; console.log(re.test('==')); console.log('Match:', re.test('='));
true Match: false
r2-p007 · Strict mode regex usage
1"use strict";
2(function() {
3 const result = /=(.+)/.test('=value') ? RegExp.$1 : 'none';
4 console.log(result);
5})();
--- orig.js 2026-10-22 14:15:32.846239897 -0400 +++ fixed.js 2026-10-22 14:15:35.756320788 -0400 @@ -1,5 +1,5 @@ "use strict"; (function() { - const result = /=(.+)/.test('=value') ? RegExp.$1 : 'none'; + const result = /[=](.+)/.test('=value') ? RegExp.$1 : 'none'; console.log(result); })();
value
r2-p008 · This binding in arrow vs function with regex
1const obj = {
2 value: 42,
3 check: function() {
4 return /=/.test(this.value.toString());
5 },
6 checkArrow: () => /=/.test(this.value.toString())
7};
8console.log(obj.check());
9console.log(obj.checkArrow());
10const fn = obj.check;
11console.log(fn());
--- orig.js 2026-10-22 14:15:32.896241280 -0400 +++ fixed.js 2026-10-22 14:15:35.206305452 -0400 @@ -1,9 +1,9 @@ const obj = { value: 42, check: function() { - return /=/.test(this.value.toString()); + return /[=]/.test(this.value.toString()); }, - checkArrow: () => /=/.test(this.value.toString()) + checkArrow: () => /[=]/.test(this.value.toString()) }; console.log(obj.check()); console.log(obj.checkArrow());
false