Like @Abelisto commented, you cannot refer to SELECT list expressions from the WHERE (or JOIN) clause of the same command because expressions in the WHERE clause are evaluated first. Consider the sequence of events:
You need a subquery or CTE to avoid repeating the expression. However, your expressions are not exactly the same to begin with. You extract a simple text as json and use the same as actual text in the JOIN clause. The extraction is tricky by itself. Consider:
test=# SELECT json '"foo"' #>> '{}';
?column?
----------
foo
#>> is the operator to ...
Get JSON object at specified path as text
Passing an empty array as path ({}) extracts text from the simple json text. Related:
Now, to avoid repeating the extract path, extract state in the CTE or in a subquery and apply the above expression in the outer SELECT:
SELECT DISTINCT ON (a.place_id)
a.state
, a.full_json -> 7 -> 'long_name' AS postal_code
, a.full_json #> '{3,short_name}' AS city -- alternative syntax, btw.
FROM (
SELECT full_json -> 5 -> 'short_name' AS state -- once!
, full_json
FROM addresses_autocomplete
WHERE json_array_length(full_json) > 7
AND formatted = $1
) a
JOIN regions r ON r.short_name = t.state #>> '{}' -- key element!
WHERE r.country_id = 1
-- ORDER BY place_id, ??? -- put expression(s) here to get deterministic pick
Equivalent to your original. While being at it I simplified the query, inlined the CTEs (don't use CTEs unless needed before Postgres 12, they typically add cost) and added ORDER BY, which will be required to get a deterministic result.
About DISTINCT ON & ORDER BY:
But are you sure you want postal_code, city and state as type json? That's an odd requirement.
Also, the above query may not produce the best query plan. The key to performance is to support the most selective predicates with optimal indexes. Repeating an expression hardly matters. You might want this instead:
SELECT DISTINCT ON (a.place_id)
a.full_json #>> '{5,short_name}' AS state
, a.full_json #>> '{7,long_name}' AS postal_code
, a.full_json #>> '{3,short_name}' AS city
FROM addresses_autocomplete a
JOIN regions r ON r.short_name = a.full_json #>> '{5,short_name}' -- back to repeating
WHERE a.formatted = $1
AND json_array_length(a.full_json) > 7
AND r.country_id = 1
-- ORDER BY a.place_id, ???