Reputation: 13
I need to select rows from postgres where a part number has a three digit number (300-399) near the beginning. I just need a match/no match.
I'm mostly there with:
WHERE name ~ '^[A-Z]{0,5}3[0-9]{2}[^0-9]?*'
The part numbers
These should match:
These should not match:
With the above, the 'should match' pass, but the 'should not match' are also passing. It seems the question mark that checks for a non-digit ([^0-9]?) allows the digits through, but I can't make it required since a simple 3-digit part number would not match.
Thanks!
Upvotes: 1
Views: 2445
Reputation: 163632
The pattern you tried could possibly also match the first 3 digits in a string with 4 digits as the character class at the end is optional [^0-9]?
If you don't make it optional [^0-9]
, it would not match a only 323
as there is a character expected after it which is any char except a digit.
If there can be characters after the number, but not a digit, you can use a negative lookahead (?!\d)
to assert not a digit directly to the right.
^[A-Z]{0,5}3[0-9]{2}(?!\d)
Explanation
^
Start of string[A-Z]{0,5}
Match 0-5 times a char A-Z3[0-9]{2}
Match 3
and 2 digits(?!\d)
Negative lookahead, assert what is directly to the right is not a digitUpvotes: 0
Reputation: 12494
This regexp passes all your tests.
'^[^\d]{0,5}\d{1,3}(\y|[^\d])'
The first caret ^
anchors to the start.
The [^\d]{0,5}
allows up to five non-digit characters.
The \d{1,3}
allows one to three each digit characters.
The (\y|[^\d])
alternation matches either a non-digit character or a word boundary such as the end of the string.
Upvotes: 1