Regex for a certain number of digits - regex

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
can be just 3 digits long,
can have up to 5 characters before the number
can have characters after the number
must exclude 4 digit numbers
These should match:
323
A335
AB359-B2
BB311BB
These should not match:
3234
A3357
AB3590-B
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!

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.

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-Z
3[0-9]{2} Match 3 and 2 digits
(?!\d) Negative lookahead, assert what is directly to the right is not a digit
Regex demo | Postgresql demo

Related

Regex to match string of limited length and if number digit are present it can't be more than 5 digit

im looking for regex that can match string with requirement below.
must be 5 to 15 characters
Alphanumeric, can accept fully alphabet, if numeric are present, it must not exceed 5 digit and it can be in anywhere in the string.
Example accepted input
helloworld
123helloworld56
1h2e3l4l5oworld
12345
if the numeric digit exceeded 5 it shall be rejected. Example rejected input:
123456
123hello4567
So far i have tried while looking online and done some tweaking, but none work as expected.
^(?=.*\d?.*\d?.*\d?.*\d?.*\d?).{0,15}$
^(?=[a-zA-Z1-9]{5,15}$)[a-zA-Z]{1,15}[1-9]{0,5}$
^(?=.*\d){0,5}.{0,15}$
I have stuck on this for some time now, any help are appreciated!
If there can not be more than 5 digits in total, that means you should not be able to match 6 digits.
You can use a negative lookahead to assert what is on the right can not match 6 digits.
^(?!(?:[^\d\r\n]*\d){6})[a-zA-Z0-9]{5,15}$
Explanation
^ Start of string
(?! Negative lookahead, assert what is at the right is not
(?:[^\d\r\n]*\d){6} Match 6 times any char except a newline or a digit, then match a digit
) Close lookahead
[a-zA-Z0-9]{5,15} Match 5-15 times any of the listed in the character class
$ End of string
Regex demo
Note that using [1-9] in a character class does not match the 0, and \d will
About the patterns in the question
^(?=.*\d?.*\d?.*\d?.*\d?.*\d?).{0,15}$
Here, the lookahead will always be true as all the parts in it are optional. It could also match an empty string as the quantifier {0,15} starts at 0, which makes it optional.
^(?=[a-zA-Z1-9]{5,15}$)[a-zA-Z]{1,15}[1-9]{0,5}$
The pattern asserts a string with 5-15 times any of the listed in the character class. But the matching starts with 1-15 times a char a-zA-Z followed by matching 0-5 times a digit at the end of the string.
^(?=.*\d){0,5}.{0,15}$
The pattern optionally asserts 0-5 digits which is always true as it is optional. Then it matches 0-15 times any char.

Max length ignoring one character in Regex

I have a Regex Which allows up to 6 decimals("." is the decimal separator)
/^\d*[.]?\d{0,6}$/
I also want to put max length condition so that user can only enter 12 digits and max length should exclude "." how do I do that with Regex.
You could use a positive lookahead to check for either a number with a decimal place with up to 6 digits after it or a string of 12 digits) and then match up to 13 characters in total:
^(?=\d*\.\d{0,6}$|\d{1,12}$).{1,13}$
For this input, the 2nd and 5th values will match:
1234567890123
123456.789012
12345.6789012
1234567.890123
12345.67890
Demo on regex101
We could try using negative lookaheads:
^(?:(?!.*\.)(?!\d{13})|(?=.*\.)(?![0-9.]{14}))\d+(?:\.\d{1,6})?$
Demo
Here is an explanation of the regex:
^(?: from the start of the string
(?!.*\.)(?!\d{13}) assert that no more than 12 digits appear
(in the case of a number with NO decimal point)
| or
(?=.*\.)(?![0-9.]{14})) assert that no more than 13 digits/decimal point appears
(in the case of a number which HAS a decimal point)
\d+ then match one or more digits (whole number portion)
(?:\.\d{1,6})? followed by an optional decimal component (1 to 6 digits)
$ end of the string
TL;DR;
^(?!(?:\D*\d){13})\d*[.]?\d{0,6}$
^(?=(?:\D*\d){0,12}\D*$)\d*[.]?\d{0,6}$
You can use a simple positive lookahead approach: keep your pattern (if it works as you expect) and insert
(?=(?:\D*\d){0,x}\D*$)
right after ^ and change the x to the required amount of digits.
So, you may use
^(?=(?:\D*\d){0,12}\D*$)\d*[.]?\d{0,6}$
^^^^^^^^^^^^^^^^^^^^^^^
The (?=(?:\D*\d){0,12}\D*$) matches a location that is immediately followed with zero to 12 occurrences of any 0+ non-digit chars followed with one digit one and then having any 0+ non-digits to the end of the string.
See the regex demo
Alternatively, disallow a string with more than 13 digits:
^(?!(?:\D*\d){13})\d*[.]?\d{0,6}$
^^^^^^^^^^^^^^^^^
The (?!(?:\D*\d){13}) is a negative lookahead that fails the match if there are 13 occurrences of any 0+ non-digits followed with a single digit chars.
This is better than the positive lookahead approach when you need to allow an empty string.
See the regex demo

Regexp struggling

I am trying to match a string (length =4) with lower case letters and digits. That could be 4 digits but not 4 letters. For example I want to match:
d4rt
df5h
34d6
4567
But not 'erty'.
I get that pattern ([a-z]+|[0-9]+){4} but that keeps me the 4 letters case.
Your regex ([a-z]+|[0-9]+){4} uses an alternation which will either match 1+ lowercase characters or 1+ digits in a capturing group and repeat that 4 times. That would also match 4 letters.
If lookarounds are supported, you could use a negative lookahead to assert that what follows are not 4 lowercase characters.
To match a string with length of 4, you could use anchors to assert the start ^ and the end $ of the string.
^(?![a-z]{4})[a-z0-9]{4}$
Regex demo
Your expression is matching four {4} of whatever either any number greater than 1 of lower case letters [a-z] or any number greater than one of digits. Therefore, your code is actually matching more than 4 of letters or digits too.
Your problem can be solved with lookaheads.
(?=[a-z]{0,3}[0-9])[a-z0-9]{4}
(?=[a-z]*[0-9]) looks ahead to find zero or more letters until it finds a number. But when it finds, such a sequence it will continue matching from the beginning of the lookahead. Thin of it as a sort of "pre match".
[a-z0-9]{4} This part checks for four numbers or lower case characters, but we are already sure that there is at least one number there because of the lookahead.
As your requirement says, the string should contain at least one digit and rest can be anything containing digits and lowercase alphabets of exactly 4 characters, you can use this regex,
^(?=.*\d)[a-z0-9]{4}$
Explanation:
^ --> Start of input
(?=.*\d) --> Look ahead to ensure the input contains at least one digit
[a-z0-9]{4} --> Ensures only lowercase alphabets and digits are matched in allowed character set
$ --> End of input
Demo

Regex: at least one of the first two character has to be a letter

I am searching for a regex which cover this usecases:
The length of the string is 8
The first two characters "can" contain 1 digit, the rest of the 6 Charatcers are digits
Two digits at the beginning are not allowed
Examples:
AB123456 --> good
1A789563 --> good
A2547896 --> good
11111111 --> BAD
I tried with:
/^[a-zA-Z]{2}\d{6}$/
But this allow two digits at the beginning.
Thank you for your help.
You may use a "spelled-out" regex approach where you list all possible variations in a grouping construct with alternation operators:
^(?:[a-zA-Z][0-9]|[0-9][a-zA-Z]|[a-zA-Z]{2})[0-9]{6}$
Or, if your regex engine supports lookaheads
^(?![0-9]{2})[0-9a-zA-Z]{2}[0-9]{6}$
See the first regex demo and the second regex demo.
The ^ asserts the position at the start of the string, then the (?:[a-zA-Z][0-9]|[0-9][a-zA-Z]|[a-zA-Z]{2}) non-capturing group matches a letter + digit, digit + letter or just two letters. Then, [0-9]{6} matches 6 digits up to the end of the string ($).
The second regex matches the start of a string (^), then fails the match if the first two chars are digits ((?![0-9]{2})), then matches two alphnumeric chars ([0-9A-Za-z]{2}) and then six digits ([0-9]{6}), and asserts the position at the end of the string ($).

regex regular expression for numbers

what is the best way to build a regex for numbers between 10 and 240, and another one between 10 and 360?
Regexes are no good to deal with numbers. Unless this is the only alternative that you got, you should probably choose another solution.
10-240: ^(?:2(?:[0-3]\d|40)|1\d\d|[1-9]\d)$
Explanation:
^: Anchor that match the beginning of the string
(?: Non-capturing group (more performant than capturing groups). I use those for alternation.
2: Literal character '2'
[0-3]: A single digit between 0 and 3.
\d: A single digit character (0-9)
|: Or
3-6. 2(?:[0-3]\d|40): A number that starts with 2 followed by 0-3 and any digit or literally '40'. That match 200-240
|1\d\d: Or one followed by two digits (0-9). That match 100-199.
|[1-9]\d : Or a digit between 1-9 followed by any digit (0-9). That match 10-99.
$: Anchor that match the end of the string.
Test it here: https://regex101.com/r/rO4fZ0/1
10-360: ^(?:3(?:[0-5]\d|60)|[12]\d\d|[1-9]\d)$
3(?:[0-5]\d|60): Literal character 3 followed by 0-5 and any digit or literally 60. That match 300-360.
|[12]\d\d: Or one or two followed by two digits (0-9). That match 100-299.
|[1-9]\d : Or a digit between 1-9 followed by any digit (0-9). That match 10-99.
Test it here: https://regex101.com/r/lD8oM4/1
The best way to do so, is with a tester, http://regexr.com
Here is the RegEx for the 10 to 240 match.
^(([1-9][0-9])|(1[0-9][0-9])|(2[0-3][0-9])|(240))$
However, I do feel this is probably not the right tool of what you want to achieve.
Mike