Rules / Correctness / valid-regexps
valid-regexps
Disallow RegExp patterns that are structurally invalid.
Flags a RegExp constructed from a string literal whose pattern is
unmistakably broken — unbalanced (/) groups, an unterminated [...]
character class, or a trailing backslash. Such a pattern throws a
FormatException the moment the RegExp is built, so catching it statically
turns a runtime crash into a lint. The check is deliberately conservative: it
inspects only literal, non-interpolated patterns and applies a structural
test rather than a full regex parse, so it never false-positives on the
JavaScript-flavored constructs (lookahead, backreferences, named groups) that
Dart's RegExp accepts. Interpolated patterns, and non-raw literals
containing backslash escapes, are skipped.
Invalid
example.dartdart
// Bad: literal patterns that are structurally invalid regular expressions.
void examples() {
final a = RegExp('(');
final b = RegExp(')');
final c = RegExp('[a-z');
final d = RegExp('(abc');
final e = RegExp('a(b(c)');
final f = new RegExp('foo)');
print([a, b, c, d, e, f]);
}
Invalid regular expression: unbalanced groups or character class.
2void examples() {
3 final a = RegExp('(');
∙
Invalid regular expression: unbalanced groups or character class.
3 final a = RegExp('(');
4 final b = RegExp(')');
∙
Invalid regular expression: unbalanced groups or character class.
4 final b = RegExp(')');
5 final c = RegExp('[a-z');
∙
Invalid regular expression: unbalanced groups or character class.
5 final c = RegExp('[a-z');
6 final d = RegExp('(abc');
∙
Invalid regular expression: unbalanced groups or character class.
6 final d = RegExp('(abc');
7 final e = RegExp('a(b(c)');
∙
Invalid regular expression: unbalanced groups or character class.
7 final e = RegExp('a(b(c)');
8 final f = new RegExp('foo)');
∙
Valid
example.dartdart
// Good: valid patterns, or patterns that are not statically checkable literals.
void examples(String dynamicPattern) {
final a = RegExp('abc');
final b = RegExp('[a-z]+');
final c = RegExp('(foo|bar)');
final d = RegExp('a(b(c)d)e'); // balanced nested groups
final e = RegExp(r'\d{3}-\d{4}'); // raw string, balanced
final f = RegExp('\\d+'); // non-raw with escapes — pattern not resolved, skipped
final g = RegExp(dynamicPattern); // not a literal, skipped
final h = RegExp('prefix-${dynamicPattern}'); // interpolated, skipped
print([a, b, c, d, e, f, g, h]);
}
How to configure
Set the severity of valid-regexps in your falcon.json:
falcon.jsonjson
{
"linter": {
"rules": {
"correctness": {
"valid-regexps": "error"
}
}
}
}