Код товара выглядит как abcd2343, что разбивать по буквам и цифрам

У меня есть список кодов продуктов в текстовом файле, в каждом лайке есть код продукта, который выглядит так:

abcd2343 abw34324 abc3243-23A

Таким образом, это буквы, за которыми следуют цифры и другие символы.

Я хочу разделить по первому вхождению числа.


person Blankman    schedule 27.07.2010    source источник


Ответы (5)


In [32]: import re

In [33]: s='abcd2343 abw34324 abc3243-23A'

In [34]: re.split('(\d+)',s)
Out[34]: ['abcd', '2343', ' abw', '34324', ' abc', '3243', '-', '23', 'A']

Или, если вы хотите разделить первое вхождение цифры:

In [43]: re.findall('\d*\D+',s)
Out[43]: ['abcd', '2343 abw', '34324 abc', '3243-', '23A']

  • \d+ соответствует 1 или более цифрам.
  • \d*\D+ соответствует 0 или более цифрам, за которыми следует 1 или более нецифр.
  • \d+|\D+ соответствует 1 или более цифрам или 1 или более нецифрам.

Подробнее о синтаксисе регулярных выражений Python см. в документах.


re.split(pat, s) разделит строку s, используя pat в качестве разделителя. Если pat начинается и заканчивается круглыми скобками (чтобы быть «группой захвата»), то re.split также вернет подстроки, соответствующие pat. Например, сравните:

In [113]: re.split('\d+', s)
Out[113]: ['abcd', ' abw', ' abc', '-', 'A']   # <-- just the non-matching parts

In [114]: re.split('(\d+)', s)
Out[114]: ['abcd', '2343', ' abw', '34324', ' abc', '3243', '-', '23', 'A']  # <-- both the non-matching parts and the captured groups

Напротив, re.findall(pat, s) возвращает только те части s, которые соответствуют pat:

In [115]: re.findall('\d+', s)
Out[115]: ['2343', '34324', '3243', '23']

Таким образом, если s заканчивается цифрой, вы можете не заканчивать пустой строкой, используя re.findall('\d+|\D+', s) вместо re.split('(\d+)', s):

In [118]: s='abcd2343 abw34324 abc3243-23A 123'

In [119]: re.split('(\d+)', s)
Out[119]: ['abcd', '2343', ' abw', '34324', ' abc', '3243', '-', '23', 'A ', '123', '']

In [120]: re.findall('\d+|\D+', s)
Out[120]: ['abcd', '2343', ' abw', '34324', ' abc', '3243', '-', '23', 'A ', '123']
person unutbu    schedule 27.07.2010
comment
Если вы используете '(\d+)', а цифра является последним символом строки, последняя запись в списке будет пустой строкой. Как этого избежать? - person user124384; 15.10.2016
comment
IIUC, вы можете использовать re.findall('(\d+|\D+)', 'abcd2343 abw34324 abc3243-23'), который возвращает ['abcd', '2343', ' abw', '34324', ' abc', '3243', '-', '23']. - person unutbu; 15.10.2016

import re

m = re.match(r"(?P<letters>[a-zA-Z]+)(?P<the_rest>.+)$",input)

m.group('letters')
m.group('the_rest')

Это покрывает ваш угловой случай abc3243-23A и ​​выводит abc для группы букв и 3243-23A для the_rest

Поскольку вы сказали, что все они находятся в отдельных строках, вам, очевидно, нужно будет помещать строку за раз в input

person jwsample    schedule 27.07.2010

Разделить по первой цифре

parts = re.split('(\d.*)','abcd2343')      # => ['abcd', '2343', '']
parts = re.split('(\d.*)','abc3243-23A')   # => ['abc', '3243-23A', '']

Таким образом, две части всегда являются частями [0] и частями [1].

Конечно, вы можете применить это к нескольким кодам:

>>> s = "abcd2343 abw34324 abc3243-23A"
>>> results = [re.split('(\d.*)', pcode) for pcode in s.split(' ')]
>>> results
[['abcd', '2343', ''], ['abw', '34324', ''], ['abc', '3243-23A', '']]

Если каждый код находится в отдельной строке, то вместо s.split( ) используйте s.splitlines().

person Muhammad Alkarouri    schedule 27.07.2010

Эта функция также обрабатывает числа с плавающей запятой и отрицательные числа.

def separate_number_chars(s):
    res = re.split('([-+]?\d+\.\d+)|([-+]?\d+)', s.strip())
    res_f = [r.strip() for r in res if r is not None and r.strip() != '']
    return res_f

Например:

utils.separate_number_chars('-12.1grams')
> ['-12.1', 'grams']
person Babak Ravandi    schedule 11.08.2020

Попробуйте этот код, он будет работать нормально

import re
text = "MARIA APARECIDA 99223-2000 / 98450-8026"
parts = re.split(r' (?=\d)',text, 1)
print(parts)

Выход:

['МАРИЯ АПАРЕСИДА', '99223-2000 / 98450-8026']

person Basant Rules    schedule 14.11.2019