Skip to content

Commit 5ab1acb

Browse files
Add no-misleading-capturing-group rule and improve optimal-quantifier-concatenation (#483)
* Simplify quantifiers * Fixed false positive for lazy quantifiers * Improved absorb condition * Added more tests * No non-atomic groups v1 * Typo * Typos * Added trading-based detection method * Added another test case * Added docs * Added `reportBacktrackingEnds` option
1 parent fd1da8b commit 5ab1acb

11 files changed

+1353
-9
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ The rules with the following star :star: are included in the `plugin:regexp/reco
119119
| [regexp/no-escape-backspace](https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-escape-backspace.html) | disallow escape backspace (`[\b]`) | :star: |
120120
| [regexp/no-invalid-regexp](https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-invalid-regexp.html) | disallow invalid regular expression strings in `RegExp` constructors | :star: |
121121
| [regexp/no-lazy-ends](https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-lazy-ends.html) | disallow lazy quantifiers at the end of an expression | :star: |
122+
| [regexp/no-misleading-capturing-group](https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-misleading-capturing-group.html) | disallow capturing groups that do not behave as one would expect | |
122123
| [regexp/no-misleading-unicode-character](https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-misleading-unicode-character.html) | disallow multi-code-point characters in character classes and quantifiers | :wrench: |
123124
| [regexp/no-missing-g-flag](https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-missing-g-flag.html) | disallow missing `g` flag in patterns used in `String#matchAll` and `String#replaceAll` | :wrench: |
124125
| [regexp/no-optional-assertion](https://ota-meshi.github.io/eslint-plugin-regexp/rules/no-optional-assertion.html) | disallow optional assertions | :star: |

docs/rules/index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ The rules with the following star :star: are included in the `plugin:regexp/reco
2525
| [regexp/no-escape-backspace](./no-escape-backspace.md) | disallow escape backspace (`[\b]`) | :star: |
2626
| [regexp/no-invalid-regexp](./no-invalid-regexp.md) | disallow invalid regular expression strings in `RegExp` constructors | :star: |
2727
| [regexp/no-lazy-ends](./no-lazy-ends.md) | disallow lazy quantifiers at the end of an expression | :star: |
28+
| [regexp/no-misleading-capturing-group](./no-misleading-capturing-group.md) | disallow capturing groups that do not behave as one would expect | |
2829
| [regexp/no-misleading-unicode-character](./no-misleading-unicode-character.md) | disallow multi-code-point characters in character classes and quantifiers | :wrench: |
2930
| [regexp/no-missing-g-flag](./no-missing-g-flag.md) | disallow missing `g` flag in patterns used in `String#matchAll` and `String#replaceAll` | :wrench: |
3031
| [regexp/no-optional-assertion](./no-optional-assertion.md) | disallow optional assertions | :star: |
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
---
2+
pageClass: "rule-details"
3+
sidebarDepth: 0
4+
title: "regexp/no-misleading-capturing-group"
5+
description: "disallow capturing groups that do not behave as one would expect"
6+
---
7+
# regexp/no-misleading-capturing-group
8+
9+
> disallow capturing groups that do not behave as one would expect
10+
11+
- :exclamation: <badge text="This rule has not been released yet." vertical="middle" type="error"> ***This rule has not been released yet.*** </badge>
12+
13+
## :book: Rule Details
14+
15+
This rule reports capturing groups that capture less text than their pattern might suggest.
16+
17+
E.g. in `/a+(a*)/`, `(a*)` will **always** capture 0 characters because all `a`s are already consumed by `a+`. This is quite surprising behavior because `a*` suggests that the capturing group captures as many `a`s as possible.
18+
19+
Misleading capturing groups in regex indicate either unnecessary code that can be removed or an error in the regex. Which one it is, depends on the intended behavior of the regex and cannot be determined by this rule.
20+
21+
E.g. if the above example is really supposed to capture 0 characters, then the regex should be changed to `/a+()/` to make the intention explicit. Otherwise, then the parts of the regex surrounding `(a*)` have to be rewritten.
22+
23+
This rule generally assumes that the regex behaves correctly, despite its misleading form, when suggesting fixes. Suggested fixes therefor remove the misleading elements **without changing the behavior** of the regex.
24+
25+
<eslint-code-block>
26+
27+
```js
28+
/* eslint regexp/no-misleading-capturing-group: "error" */
29+
30+
/* ✓ GOOD */
31+
var foo = /a+(b*)/
32+
33+
/* ✗ BAD */
34+
var foo = /a+(a*)/
35+
var foo = /\w+(\d*)/
36+
var foo = /^(a*).+/
37+
```
38+
39+
</eslint-code-block>
40+
41+
## :wrench: Options
42+
43+
```json
44+
{
45+
"regexp/no-misleading-capturing-group": [
46+
"error",
47+
{
48+
"reportBacktrackingEnds": true,
49+
}
50+
]
51+
}
52+
```
53+
54+
- `reportBacktrackingEnds`
55+
56+
This rule will report quantifiers at the end of capturing groups that might backtrack for certain strings.
57+
58+
E.g. when `/^(a*).+$/m` is used to match the string `"aa"`, then `a*` will capture both `a`s at first, but is then force to give up the last `a` to `.+` to make the whole regex accept. So `(a*)` only capture the first `a`. This is misleading because one would expect that `(a*)` should capture all `a`s at the start of the string, but this is not the case.
59+
60+
Because this behavior might be intentional, some users might want to turn off this type of reporting.
61+
62+
## :mag: Implementation
63+
64+
- [Rule source](https://github.com/ota-meshi/eslint-plugin-regexp/blob/master/lib/rules/no-misleading-capturing-group.ts)
65+
- [Test source](https://github.com/ota-meshi/eslint-plugin-regexp/blob/master/tests/lib/rules/no-misleading-capturing-group.ts)

0 commit comments

Comments
 (0)