Before jumping at the solution, please have a look at your regex: the character classes for single ranges inside alternation groups is an inefficient way of writing regex patterns. You may simply merge these ([A-Z]|[0-9]|_)+ into [A-Z0-9_]+.
The solution may be a word boundary with a negative lookahead after it:
r"\b(?!PI\b)[_a-zA-Z][_a-zA-Z0-9]*"
See the regex demo. You may replace [a-zA-Z0-9_] with \w:
re.compile(r"\b(?!PI\b)[_a-zA-Z]\w*") # In Python 2.x, re.UNICODE is not enabled by default
re.compile(r"\b(?!PI\b)[_a-zA-Z]\w*", re.A) # In Python 3.x, make \w match ASCII only
Details
\b - word boundary
(?!PI\b) - immediately to the right, there can't be PI as a whole word
[_a-zA-Z] - an ASCII letter or _
[_a-zA-Z0-9]* - 0 or more underscores, ASCII letters or digits.
PIthat you want to exclude?r"\b(?!PI\b)[_a-zA-Z][_a-zA-Z0-9]*"? See demo.