Разделение строки, в которой она переключается между числовыми и буквенными символами
Я разбираю некоторые данные, где стандартный формат - это что-то вроде 10 pizzas
. Иногда данные вводятся правильно, и мы можем в итоге 5pizzas
вместо 5 pizzas
. В этом случае я хочу проанализировать количество пицц.
Наивный способ сделать это состоял бы в том, чтобы проверить символ по символу, создав строку до тех пор, пока мы не достигнем цифры, а затем произведем ее как целое число.
num_pizzas = ""
for character in data_input:
if character.isdigit():
num_pizzas += character
else:
break
num_pizzas = int(num_pizzas)
Это довольно неуклюже. Есть ли более простой способ разделить строку, где она переключается с числовых цифр на буквенные символы?
Ответы
Ответ 1
Вы запрашиваете способ разделить строку на цифры, но тогда в вашем примере то, что вы на самом деле хотите, это просто первые числа, это легко сделать с помощью itertools.takewhile()
:
>>> int("".join(itertools.takewhile(str.isdigit, "10pizzas")))
10
Это имеет большой смысл - то, что мы делаем, это взять символ из строки, пока они являются цифрами. Это имеет преимущество остановки обработки, как только мы переходим к первому несимметричному символу.
Если вам нужны и более поздние данные, то то, что вы ищете, itertools.groupby()
смешивается с простым список:
>>> ["".join(x) for _, x in itertools.groupby("dfsd98sd8f68as7df56", key=str.isdigit)]
['dfsd', '98', 'sd', '8', 'f', '68', 'as', '7', 'df', '56']
Если вы хотите сделать одно гигантское число:
>>> int("".join("".join(x) for is_number, x in itertools.groupby("dfsd98sd8f68as7df56", key=str.isdigit) if is_number is True))
98868756
Ответ 2
Чтобы разбить строку на цифры, вы можете использовать re.split
с регулярным выражением \d+
:
>>> import re
>>> def my_split(s):
return filter(None, re.split(r'(\d+)', s))
>>> my_split('5pizzas')
['5', 'pizzas']
>>> my_split('foo123bar')
['foo', '123', 'bar']
Чтобы найти первое число, используйте re.search
:
>>> re.search('\d+', '5pizzas').group()
'5'
>>> re.search('\d+', 'foo123bar').group()
'123'
Если вы знаете, что номер должен быть в начале строки, вы можете использовать re.match
вместо re.search
. Если вы хотите найти все цифры и отказаться от остальных, вы можете использовать re.findall
.
Ответ 3
Как насчет регулярного выражения?
reg = re.compile(r'(?P<numbers>\d*)(?P<rest>.*)')
result = reg.search(str)
if result:
numbers = result.group('numbers')
rest = result.group('rest')