I'm trying to write a RegExp to match only 8 digits, with one optional comma maybe hidden in-between the digits.
All of these should match:
12345678
12,45678
123456,8
Right now I have:
^[0-9,]{8}
but of course that erroneously matches 012,,,67
Example: https://regex101.com/r/dX9aS9/1
I know optionals exist but don't understand how to keep the 8 digit length applying to the comma while also keeping the comma limited to 1.
Any tips would be appreciated, thanks!
To match 8 char string that can only contain digits and an optional comma in-between, you may use
^(?=.{8}$)\d+,?\d+$
See the regex demo
The lookahead will require the string to contain 8 chars. ,? will make matching a comma optional, and the + after \d will require at least 1 digit before and after an optional comma.
If you need to match a string that has 8 digits and an optional comma, you can use
^(?:(?=.{9}$)\d+,\d+|\d{8})$
See the regex demo
Actually, the string will have 9 characters in the string (if it has a comma), or just 8 - if there are only digits.
Explanation:
^ - start of string(?:(?=.{9}$)\d+,\d+|\d{8}) - 2 alternatives:
(?=.{9}$)\d+,\d+ - 1+ digits followed with 1 comma followed with 1+ digits, and the whole string matched should be 9 char long (8 digits and 1 comma)| - or\d{8} - 8 digits$ - end of stringSee the Java code demo (note that with String#matches(), the ^ and $ anchors at the start and end of the pattern are redundant and can be omitted since the pattern is anchored by default when used with this method):
List<String> strs = Arrays.asList("0123,,678", "0123456", // bad
"01234,567", "01234567" // good
);
for (String str : strs)
System.out.println(str.matches("(?:(?=.{9}$)\\d+,\\d+|\\d{8})"));
NOTE FOR LEADING/TRAILING COMMAS:
You just need to replace + (match 1 or more occurrences) quantifiers to * (match 0 or more occurrences) in the first alternative branch to allow leading/trailing commas:
^(?:(?=.{9}$)\d*,\d*|\d{8})$
See this regex demo
You can use following regex if you want to let trailing comma:
^((\d,?){8})$
Demo
Otherwise use following one:
^((\d,?){8})(?<!,)$
Demo
(?<!,) is a negative-lookbehind.
/^(?!\d{0,6},\d{0,6},\d{0,6})(?=\d[\d,]{6}\d).{8}$/
I guess this cooperation of positive and negative look-ahead does just what's asked. If you remove the start and end delimiters and set the g flag then it will try to match the pattern along decimal strings longer than 8 characters as well.
Please try http://regexr.com/3d63m
Explanation: The negative look ahead (?!\d{0,6},\d{0,6},\d{0,6}) tries not to find any commas side by side if they have 6 or less decimal characters in between while the positive look ahead (?=\d[\d,]{6}\d) tries to find 6 decimal or comma characters in between two decimal characters. And the last .{8} selects 8 characters.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With