Regex min length on complex match - regex

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

Related

validate string data using regex which allowed only numbers and - (hyphen) of length 6 but hypen should not be the end and the digits not same

Validate the string using the regex which has the - (hypen)
Requirement is : string contains only digits and - (hyphens) and not end with - (hyphen) and all other digits not be the same.
^([0-9-])(?!\1+$)[0-9-]{5}$
The above one allow only digits and hyphen but its not restricted end with hyphen and check all other digits are same.
ex:
1111-1 Not allowed because all are same digits
1111-2 Allowed
11112- Not allowed as its end with - Hypen
-12345 Not allowed as its start with - hypen
You might write the pattern as
^(\d)(?!(?:\1|-)+$)(?!\d*-\d*-)[\d-]{4}\d$
Explanation
^ Start of string
(\d) Capture a single digit in group 1
(?! Negative lookahead
(?:\1|-)+$ Check that to the right there is not only the group 1 value or hyphens
(?!\d*-\d*-) Assert not 2 hyphens
) Close lookahead
[\d-]{4} Match 4 digits or hyphens
\d Match a digit
$ End of string
Regex demo
If there should be at least 1 hyphen:
^(\d)(?!(?:\1|-)+$)(?=\d*-)[\d-]{4}\d$
Regex demo
My 2 cents to allow [01] hyphens:
^(?=.{6}$)(\d)(?=.*(?!\1)\d)\d+(?:-\d+)?$
See an online demo

Regular Expression positive lookbehind

I would like to create a regex, that allowes the following patterns:
1234
1234567
123456789
12345678900-
12345678900-123456
It should be possible to only insert numbers and only one hyphen is allowed.
I tried with the following regex:
^[0-9]{1,11}(?(?<=\d{11})[-]?|)[0-9]{6}
It should not be possible to have 11 characters without the hyphen at the end(12345678900 is wrong).
Unfortunatly it didnt work as I intended.
You can match 1-10 digit and optionally match 1 digit followed by - and 6 digits.
^\d{1,10}(?:\d?-(?:\d{6})?)?$
^ Start of string
\d{1,10} Match 1-10 digits
(?: Non capture group
\d?- Match a single optional digit and -
(?:\d{6})? Match optional 6 digits
)? Close non capture group and make it optional
$ End of string
Regex demo
Another variation could be matching 1-10 digits or match 11 digits with a hyphen and optionally 6 digits if the hyphen should only possible after 11 digits.
^(?:\d{1,10}|\d{11}-(?:\d{6})?)$
Regex demo
You can use
^[0-9]{1,11}(?:(?<=[0-9]{11})-(?:[0-9]{6})?)?$
^\d{1,11}(?:(?<=\d{11})-(?:\d{6})?)?$
See the regex demo. Using \d is possible in case it matches ASCII digits in your regex flavor or you do not care if \d matches all possible Unicode digit chars or not.
Details:
^ - start of string
[0-9]{1,11} - one to eleven digits
(?:(?<=[0-9]{11})-(?:[0-9]{6})?)? - an optional occurrence of
(?<=[0-9]{11}) - immediately to the left there must be 11 digits
- - a hyphen
(?:[0-9]{6})? - an optional occurrence of six digits
$ - end of string.

Regex for a permutation of exactly 7 digits and 2 hyphens, without 2 consecutive hyphens

I a looking for a Regex to match a string which should:
start with a digit
'in-between' have a permutation of exactly 7 digits and 2 hyphens, without 2 consecutive hyphens
end with a sequence of digit, hyphen, digit
Match:
01-234-5678-9
01234-56-78-9
0123-4-5678-9
012-345-678-9
01-234567-8-9
01-234-5678-9
0-12345-678-9
0-123-45678-9
0-123-45678-9
01-23456-78-9
0-123456-78-9
0-1234567-8-9
No Match:
01-234-56789-0
01-234-567-8
01--2345678-9
01-2345678--9
0-1-23456789
-01-2345678-9
For now, I could not quite figure out how to match the 2 'in-between' hyphens: ^\d\d{7}\d-\d$
EDIT:
Thanks to the answers I had to this question, I was able to expand it to this other question regarding ISBN-10 and ISBN-13...
You can assert 7 digits and the digit - digit part at the end.
For the match there should be at least a single digit before and after the hyphen to prevent consecutive hyphens.
^\d(?=(?:-?\d){7}-?\d-\d$)\d*-\d+-\d*\d-\d$
^ Start of string
\d Match a single digit
(?= Positive lookahead
(?:-?\d){7} Match 7 digits separated by an optional -
-?\d-\d$ Match an optional - and the \d-\d$ at the end
) Close the lookahead
\d*-\d+-\d*\d-\d Match possible formats where all hyphens are separated by at least a single digit
$ End of string
Regex demo
My two cents:
^(?=.{11}-\d$)(?:\d+-){3}\d
See the online demo
^ - Start string anchor.
(?= - Open positive lookahead:
.{11}-\d$ - Any character other than newline 11 times followed by a hypen, a single digit and the end string anchor.
) - Close positive lookahead.
(?: - Open non-capture group:
\d+- - 1+ digit followed by an hyphen.
){3} - Close non-capture group and match three times.
\d - Match a single digit.
I guess alternatively even ^(?=.{13}$)(?:\d+-){3}\d$ would work.

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

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})?$