PatternRegex

Match an env variable assignment

Match a KEY=value assignment line in a .env file — an uppercase name followed by an equals sign and whatever value trails it to end of line.

Last updated

Patternm
^[A-Z][A-Z0-9_]*=.*$
Open in Regex Tester & Builder

Matches

  • API_KEY=sk-12345 DEBUG=true
  • PORT=3000

Doesn’t match

  • export FOO=bar
  • api_key=lowercase

Why it’s written this way

[A-Z][A-Z0-9_]* requires the name to start with an uppercase letter and continue with uppercase letters, digits or underscores — the SCREAMING_SNAKE_CASE convention essentially every .env file, Docker Compose file and shell export list follows. The = is literal, and .* takes whatever follows as the value, unquoted or not.

The m flag is what makes this useful against a whole file rather than a single line: it makes ^ and $ match at the start and end of every line instead of just the start and end of the entire string, so scanning a multi-line .env in one pass finds every assignment.

Edge cases to know

  • →Without the m flag this pattern only checks the very first line of a multi-line string — it is easy to forget to pass the flag through and quietly match nothing.
  • →It does not understand quoting, so a value containing a literal newline inside quotes (rare, but valid in some .env parsers) will get cut off at the line break.
  • →Lowercase or mixed-case variable names, which some tools do allow, will not match — this pattern encodes the uppercase convention deliberately, not the full range of what shells permit.

Part by part

^
Start of a line rather than start of the string, because the m flag is set. That is what lets one pass scan a whole .env file.
[A-Z]
A required uppercase first letter. Environment variable names cannot start with a digit, and the convention is uppercase throughout.
[A-Z0-9_]*
The rest of the name: uppercase letters, digits and underscores, which is the portable character set for environment names.
=
The literal separator. Exactly one, and everything after it is the value.
.*$
The value: anything at all to the end of the line, including an empty string, since an assignment with no value is legal.

Common mistakes

  • ^[A-Za-z_][A-Za-z0-9_]*=.*$

    Allowing lowercase matches shell variables and ordinary assignments in scripts, so scanning a bash file returns every local variable alongside the environment ones you wanted.

  • ^[A-Z][A-Z0-9_]*=.*

    Without the end anchor the pattern still works on single lines but stops describing the whole assignment, which matters if you go on to use the match length or replace the line.

  • ^[A-Z][A-Z0-9_]*\s*=\s*.*$

    Allowing spaces around the equals sign matches what people write and not what the format permits — in a real .env file, KEY = value assigns the variable "KEY " or fails outright depending on the loader.

Questions

Does it handle quoted values with spaces?

It matches them, because .* takes everything to end of line, but it does not strip the quotes. Loaders differ on whether quotes are literal or delimiters, so remove them deliberately rather than assuming.

Will it match a commented-out line?

No. A leading # means the line does not start with an uppercase letter, so comments are skipped — which is the behaviour you want when reading a file where half the entries are documentation.

Does it handle multi-line values?

No. The m flag makes ^ and $ line anchors, so a value spanning several lines is truncated at the first newline. Multi-line secrets in .env files need a parser that understands the quoting rules.

Is it safe to log lines that match this?

No — this pattern finds exactly the lines most likely to contain credentials. Use it to locate assignments, then mask everything after the equals sign before the result goes anywhere it might be stored.

Related in Patterns