简体   繁体   中英

How to split a Python string with numbers and letters?

I have strings that have optional numbers and letters, such as '01a', 'b' and '02'. These strings have always two parts, numbers on the left, and letters on the right side. I'd like to split these strings to get the numbers and letters separately. How can I define mySplit in a way to get this result?

>>> map(mySplit, ['01123absd', 'bsdf', '02454'])

[('01123', 'absd'), (None, 'bsdf'), ('02454', None)]

Similar to jramirez answer , just a bit shorter:

def myFunction(s):
    return (''.join(c for c in s if c.isdigit()) or None, 
            ''.join(c for c in s if c.isalpha()) or None)

A little shorter still using filter :

def myFunction(s):
    return (''.join(filter(str.isdigit, s)) or None, 
            ''.join(filter(str.isalpha, s)) or None)

Output:

print(*map(myFunction, ['01123absd', 'bsdf', '02454', '012abc345def']))
('01123', 'absd') (None, 'bsdf') ('02454', None) ('012345', 'abcdef')

You can use regular expressions for this. What we want is:

  • a string that starts with 0 or more digits,
  • a string that ends with 0 or more letters.

Note that the regex will create named groups, it is also compiled once to be more efficient every time is it called.

import re
regex = re.compile("^(?P<numbers>\d*)(?P<letters>\w*)$")

def myFunction(entry):
  (numbers, letters) = regex.search(entry).groups()
  return (numbers or None, letters or None)

map(myFunction, ['01123absd', 'bsdf', '02454'])

The call on the last line gives the following output:

[('01123', 'absd'), (None, 'bsdf'), ('02454', None)]

If you don't want to use regex this is a solution:

def split_num_str(my_str):
    num = [x for x in my_str if x.isdigit()]
    num = "".join(num)

    if not num:
        num = None

    my_str = [x for x in my_str if x.isalpha()]
    my_str = ''.join(my_str)

    if not my_str:
        my_str = None

    return num, my_str

m = map(split_num_str, ['01123absd', 'bsdf', '02454'])
print m

result = [('01123', 'absd'), (None, 'bsdf'), ('02454', None)]

You can use regular expressions here:

import re

def myFunction(numbers_and_letters):
    m = re.match(r"([a-z]*)([0-9]*)", numbers_and_letters)
    return tuple(v == "" and None or v for v in m.groups())
import re


def myFunction(t):
    m = re.match(r"([a-z]*)([0-9]*)", t)
    x,y = m.groups()
    if x=='': x= None    
    if y=='': y= None    
    return ((x,y))

for s in ['01123absd', 'bsdf', '02454']:
    print myFunction(s)

produces:

(None, '01123')
('bsdf', None)
(None, '02454')

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM