ISIN format is defined by ISO 6166. The last character is a single check digit. So regex is not enough in theory.
One option is to iterate on all 12 character [A-Z]{2}[A-Z0-9]{9}[0-9]
sequences and verify the checksum. In any normal text, that should be enough.
for isin in re.findall(isin_regex, text):
If check_isin(isin):
print('ISIN found: %s' % isin)
One could even argue that the probability of a wrong ISIN in a common text is very small and we could do without the check.
For the sake of the discussion, assuming the text is any sequence of data, re.findall
is no longer an option because it only finds non overlapping sequences. Which means a wrong ISIN could hide a real one. This question has already been answered elsewhere.
If performance is an issue and you are in a complex case, it should be possible to implement a DFA like algorithm to find them in near linear complexity.