2

I currently have the following regular expression:

/(_|[a-z]|[A-Z])(_|[a-z]|[A-Z]|[0-9])*/

I would like the expression not to match with "PI", however I failed to do so. To clarify, I would like the following to be valid: _PI, abcPI, PIpipipi I just dont want to accept PI when its on its own.

2
  • So do you want more than two characters? or is it only PI that you want to exclude? Commented Feb 22, 2019 at 21:58
  • Maybe r"\b(?!PI\b)[_a-zA-Z][_a-zA-Z0-9]*"? See demo. Commented Feb 22, 2019 at 22:06

3 Answers 3

2

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.
Sign up to request clarification or add additional context in comments.

Comments

0

Submitting another answer: ^(((?!PI).)*)$|^.*(PI).+$|^.+(PI).*$

I broke it down into 3 cases using OR |:

1) Match a string that doesn't contain PI at all.

^(((?!PI).)*)$

2) Match a string that has PI in it but has at least one character behind it, and optionally any characters ahead of it.

^.*(PI).+$

3) Match a string that has PI in it but has at least one character ahead of it, and optionally any characters behind it.

^.+(PI).*$

Here it is with test cases: https://regex101.com/r/7rzqpe/3

Please comment if you find a missing edge case.

Comments

0

Not very nice, but I'll add it anyway for variety:

/^([A-OQ-Za-z_][A-Za-z0-9_]*|P([A-HJ-Za-z0-9_][A-Za-z0-9_]*)?)$/

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.