Max length ignoring one character in Regex - 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

Related

Regex for a certain number of digits

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

Regex min length on complex match

I have the following regex:
^(?P<wrap_0>\()?[-+]?((?P<whole_part>\d+\.?)|(?P<decimal_part>\d*\.\d+))(?(wrap_0)\))$
Is there a way to assert that the whole_part + decimal_part is at least 8 chars in length? In other words, this should match:
1029.20384 # yes
102 # no, length of 3 < 8
Existing regex here: https://regex101.com/r/rTrCeB/1 (PCRE / php flavor).
You could use an alternation here:
^(\d{8,}|(?=[0-9.]{8,})\d+(?:\.\d+))$
Demo
Here is an explanation of the regex:
^ from the start of the string
(
\d{8,} match a pure number (no decimal component) of 8 or more digits
| OR
(?=[0-9.]{8,}) assert that 8 or more digits or decimal point occurs
\d+(?:\.\d+) then match a number followed by a decimal component
)
$ end of the string
You could use a positive lookahead to assert at least 8 times a digit or dot on the right and then match 1+ digits with an optional decimal part.
^(?=[\d.]{8,}$)\d+(?:\.\d+)?$
In parts
^ Start of string
(?=[\d.]{8,}$) Positive lookahead, assert 8 or more times either a dot or digit
\d+ Match
(?:\.\d+)? Optionally match a dot and 1+ digits
$ End of string
Regex demo

regex to match exactly 16 consecutive digits in a potentially larger string [duplicate]

This question already has answers here:
Java REGEX to match an exact number of digits in a string
(5 answers)
Closed 3 years ago.
I need a regular expression that will match exactly 16 consecutive digits, no more or less, regardless of what, if anything, is surrounding it. I've gone through a couple iterations but all have had issues:
\d{16} will match any 16 consecutive digits, including 16 digits within a longer string of digits
^\d{16}$ will match a line that is exactly 16 consecutive digits, but if there is anything else in the string, the match will fail
\D\d{16}\D will match a string of 16 consecutive digits, but only if it is surrounded by non-digit characters. If the string of 16 digits is alone on the line, it fails
\D?\d{16}\D? will match a longer string of consecutive digits
[\D^]\d{16}[\D$] does not treat ^ and $ as their special meanings, but rather treats them as literal characters.
How can I create the regex I need?
Edit: These are PCRE regex
You can use lookaround
(?<!\d)\d{16}(?!\d)
(?<!\d) - Match should not be preceded by digit
\d{16} - Match digits (0 - 9) 16 times
(?!\d) - Match should not be followed by digit
Regex demo
This is close D\d{16}\D to what you want, except, as you noted, it grabs the non-digits surrounding the 16-digit sequence. Modify it with a lookbehind and a lookahead to use non-digits as anchors, without including them in a match:
(?<!\d)\d{16}(?!\d)
(?<=\D|^)\d{16}(?=\D|$)
The key here is positive lookarounds. These can verify nondigit characters without capturing them.
(?<=\D|^) Ensure that behind the match is either a nondigit character or the start of the string
\d{16} Capture exactly 16 digits
(?=\D|$) Ensure that following the match is either a nondigit character or the end of the string
Demo

Regex to validate numbers before and after decimal excluding comma

I am trying to validate decimal number of 13 digit before and 4 digit after dot excluding comma , i.e comma shouldn't be counted as a digit.
Valid Cases
1,234,567,890,123.1234
1234567890123.1234
123456789012.1234
1234567890123.123
12345.123
1.2
0
In Valid Cases
12345abc.23 // string or special characters not allowed
1,234,567,890,1231.1234
1,234,567,890,123.12341
12345678901231.1234
1234567890123.12341
Current Regex
^[0-9]{1,13}(\.[0-9]{0,4})?$
The current Regex is counting comma as a digit.
Any help would be great.
You could use a negative lookahead to assert what is directly on the right is not 14 times a digit before matching a dot:
^(?!(?:[^.\s\d]*\d){14})-?\d+(?:,\d{1,3})*(?:\.\d{1,4})?$
Explanation
^ Start of string
-? Optional hyphen
(?! Negative lookahead, assert what follows is not
(?:[^.\s\d]*\d){14} Match not a digit, whitespace char or dot 14 times
) Close lookahead
\d+ Match 1+ digits
(?:,\d{1,3})* Match comma, 1-3 digits and repeat 0+ times (Or use \d+)
(?:\.\d{1,3})? Optional part, match a dot and 1-4 digits
$ End of the string
Regex demo
You could just specify the optional count of , Like
^[0-9]{0,1}([,])?[0-9]{0,3}([,])?[0-9]{0,3}([,])?[0-9]{1,3}(\.[0-9]{0,3})?$

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