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
Regex demo
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*$
An example with JavaScript:
const regex = /^(?=[A-Z0-9]{10}$)[^0]*0*$/;
["ABC1000000", "3212130000", "0000000000", "ABC1000100", "0001000000"]
.forEach(s =>
console.log(`${s} --> ${regex.test(s)}`)
);
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
Regex demo