You could instead use:
^(?=[0-9a-zA-Z]{8})[^\d]*\d[^\d]*$
The first part would assert that the match contains 8 alphabets or digits. Once this is ensured, the second part ensures that there is only one digit in the match.
EDIT: Explanation:
- The anchors
^
and$
denote the start and end of string. (?=[0-9a-zA-Z]{8})
asserts that the match contains 8 alphabets or digits.[^\d]*\d[^\d]*
would imply that there is only one digit character and remaining non-digit characters. Since we had already asserted that the input contains digits or alphabets, the non-digit characters here are alphabets.