I have a list of product codes in a text file, on each line is the product code that looks like:
abcd2343 abw34324 abc3243-23A
So it is letters followed by numbers and other characters.
I want to split on the first occurrence of a number.
Advertisement
Answer
import re
s='abcd2343 abw34324 abc3243-23A'
re.split('(d+)',s)
> ['abcd', '2343', ' abw', '34324', ' abc', '3243', '-', '23', 'A']
Or, if you want to split on the first occurrence of a digit:
re.findall('d*D+',s)
> ['abcd', '2343 abw', '34324 abc', '3243-', '23A']
- d+matches 1-or-more digits.
- d*D+matches 0-or-more digits followed by 1-or-more non-digits.
- d+|D+matches 1-or-more digits or 1-or-more non-digits.
Consult the docs for more about Python’s regex syntax.
re.split(pat, s) will split the string s using pat as the delimiter.  If pat begins and ends with parentheses (so as to be a “capturing group”), then re.split will return the substrings matched by pat as well. For instance, compare:
re.split('d+', s)
> ['abcd', ' abw', ' abc', '-', 'A']   # <-- just the non-matching parts
re.split('(d+)', s)
> ['abcd', '2343', ' abw', '34324', ' abc', '3243', '-', '23', 'A']  # <-- both the non-matching parts and the captured groups
In contrast, re.findall(pat, s) returns only the parts of s that match pat:
re.findall('d+', s)
> ['2343', '34324', '3243', '23']
Thus, if s ends with a digit, you could avoid ending with an empty string by using re.findall('d+|D+', s) instead of re.split('(d+)', s):
s='abcd2343 abw34324 abc3243-23A 123'
re.split('(d+)', s)
> ['abcd', '2343', ' abw', '34324', ' abc', '3243', '-', '23', 'A ', '123', '']
re.findall('d+|D+', s)
> ['abcd', '2343', ' abw', '34324', ' abc', '3243', '-', '23', 'A ', '123']