Using regular expressions, how can I make sure there are nothing but zeroes after the first zero?
ABC1000000 - valid
3212130000 - valid
0000000000 - valid
ABC1000100 - invalid
0001000000 - invalid
The regex without validation would be something like this - [A-Z0-9]{10}
, making sure it is 10 characters.
CodePudding user response:
You could update the pattern to:
^(?=[A-Z0-9]{10}$)[A-Z1-9]*0 $
The pattern matches:
^
Start of string(?=[A-Z0-9]{10}$)
Positive looakhead, assert 10 allowed chars[A-Z1-9]*
Optionally match any char of[A-Z1-9]
0
Match 1 zeroes$
End of string
If a value without zeroes is also allowed, the last quantifier can be *
matching 0 or more times (and a bit shorter version by the comment of @Deduplicator using a negated character class):
^(?=[A-Z0-9]{10}$)[^0]*0*$
As an alternative without lookarounds, you could also match what you don't want, and capture in group 1 what you want to keep.
To make sure there are nothing but zeroes after the first zero, you could stop the match as soon as you match 0 followed by 1 char of the same range without the 0.
In the alternation, the second part can then capture 10 chars of range A-Z0-9.
^(?:[A-Z1-9]*0 [A-Z1-9]|([A-Z0-9]{10})$)
The pattern matches:
^
Start of string(?:
Non capture group for the alternation|
[A-Z1-9]*0 [A-Z1-9]
Match what should not occur, in this case a zero followed by a char from the range without a zero|
Or([A-Z0-9]{10})
Capture group 1, match 10 chars in range[A-Z0-9]
$
End of string)
Close non capture group
CodePudding user response:
You can use a lookahead to match a string of 10 characters. Then, just match everything but 0 from the start of the string, then only zeroes until the end of the string:
^(?=.{10}$)[^0]*0 $
This works for all of your test cases. You can change the one to many symbol after the last 0 to zero or many (*) if you don't require 0's.
var re = /^(?=.{10}$)[^0]*0 $/mi;
console.log(re.test('ABC1000000'));
console.log(re.test('3212130000'));
console.log(re.test('0000000000'));
console.log(re.test('ABC1001000'));
console.log(re.test('0001000000'));
console.log(re.test('32121300000')); // too short
console.log(re.test('321213000')); // too long
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
CodePudding user response:
You could also use negation:
^(?=[\dA-Z]{10}$)(?!.*0[^0\r\n])
(?!.*0[^0\r\n])
is a negative lookahead that asserts there is no zero followed by a non-zero other than the line terminator. It could alternatively be written (?!.*0[1-9A-Z])
.
CodePudding user response:
0[^0]
- a
0
followed by NOT a0
I've written it in JS because it was easier to test, but it works in other languages as well. Note: it does not check length, but this regex is so much easier, combine this with a length check and your done.
If the regex matches, the string is invalid :) In the console I've negated it already to tell you if it is valid:
const strings = [
'BC1000000',
'3212130000',
'0000000000',
'ABC1000100',
'0001000000',
'1000000000',
'10000000000',
'1000000001'
];
strings.forEach(element => {
console.log(
element,
// true means length 10 and only trailing zeros
!/0[^0]/.test(element) && element.length == 10
)
});
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
CodePudding user response:
If you're doing this as part of a program/script and aren't limited to just that one regex, it's probably easier to do the test in two steps. Check the zeroes in one test, check the length separately.
The regex to test if all zeroes are at the tail end is then simply ^[^0]*0*$
(or ^[A-Z1-9]*0*$
for a more limited set of allowed characters); and checking the string length is easy in any programming language.
E.g. in Perl, this would print matching input lines (chomp
removes the newline):
perl -lne 'chomp; print if /^[^0]*0*$/ && length == 10'
(or use ...0 $
(or ...00*$
in BRE) if you require at least one zero at the end.)
CodePudding user response:
If you want to find strings like that within other text (rather than anchored with ^
and $
):
(?<![A-Z0-9])(?=[A-Z0-9]{10}(?:[^A-Z0-9]|$))([^0]*0*(?=(?:[^A-Z0-9]|$)))