假设我有一个字符串,如下所示:expression = '123 + 321'
。
我按字符逐个字符地遍历字符串:for p in expression
。我正在检查p
是否是使用p.isdigit()
的数字。如果p
是一个数字,我想抓住整个数字(抓住123
和321
,而不只是p
,最初是1
)。
我怎么能用Python做到这一点?
在C中(来自C背景),等价物是:
int x = 0;
sscanf(p, "%d", &x);
// the full number is now in x
修改
基本上,我接受来自用户的数学表达式,它接受正整数,+, - ,*,/以及括号:'('和')'。我逐字逐句地走字符串,我需要能够确定字符是否是数字。使用isdigit()
,我可以。如果它是一个数字,我需要抓住整数。怎么办?
答案 0 :(得分:3)
>>> from itertools import groupby
>>> expression = '123 + 321'
>>> expression = ''.join(expression.split()) # strip whitespace
>>> for k, g in groupby(expression, str.isdigit):
if k: # it's a digit
print 'digit'
print list(g)
else:
print 'non-digit'
print list(g)
digit
['1', '2', '3']
non-digit
['+']
digit
['3', '2', '1']
答案 1 :(得分:2)
这是可以从许多不同方向处理的问题之一。以下是我认为基于itertools.takewhile
的优雅解决方案:
>>> from itertools import chain, takewhile
>>> def get_numbers(s):
... s = iter(s)
... for c in s:
... if c.isdigit():
... yield ''.join(chain(c, takewhile(str.isdigit, s)))
...
>>> list(get_numbers('123 + 456'))
['123', '456']
这甚至适用于列表理解:
>>> def get_numbers(s):
... s = iter(s)
... return [''.join(chain(c, takewhile(str.isdigit, s)))
... for c in s if c.isdigit()]
...
>>> get_numbers('123 + 456')
['123', '456']
查看其他答案,我发现这与jamylak的groupby
解决方案没有什么不同。我建议如果你不想丢弃额外的符号。但如果你想丢弃它们,我认为这有点简单。
答案 2 :(得分:1)
虽然我不熟悉sscanf
,但我不是C开发人员,看起来它使用的格式字符串与我使用python的re
模块的方式不同。像这样:
import re
nums = re.compile('\d+')
found = nums.findall('123 + 321')
# if you know you're only looking for two values.
left, right = found
答案 3 :(得分:1)
Python文档包含一个关于simulating scanf
的部分,它让您了解如何使用正则表达式来模拟scanf
(或sscanf
的行为,它们都是相同的在Python)。特别是,r'\-?\d+'
是对应于整数正则表达式的Python字符串。 (r'\d+'
表示非负整数。)因此,您可以将其嵌入循环中
integer = re.compile(r'\-?\d+')
for p in expression:
if p.isdigit():
# somehow find the current position in the string
integer.match(expression, curpos)
但这仍然反映了一种非常类似于C的思维方式。在Python中,你的迭代器变量p
实际上只是一个单独的字符,它实际上是从原始字符串中拉出来的,并且是独立的。因此,在循环中,您自然无法访问字符串中的当前位置,并且尝试计算它将不是最优的。
我建议使用Python内置的regexp匹配迭代方法:
integer = re.compile(r'\-?\d+') # only do this once in your program
all_the_numbers = integer.findall(expression)
现在all_the_numbers
是表达式中所有整数的字符串表示的列表。如果你想将它们实际转换为整数,那么你可以这样做而不是最后一行:
all_the_numbers = [int(s) for s in integer.finditer(expression)]
在这里,我使用了finditer
而不是findall
,因为在重新迭代它们以将它们转换为整数之前,您不必创建所有字符串的列表。
答案 4 :(得分:1)
您可以使用shlex
http://docs.python.org/library/shlex.html
>>> from shlex import shlex
>>> expression = '123 + 321'
>>> for e in shlex(expression):
... print e
...
123
+
321
>>> expression = '(92831 * 948) / 32'
>>> for e in shlex(expression):
... print e
...
(
92831
*
948
)
/
32
答案 5 :(得分:0)
e_array = expression.split('+')
i_array = map(int, e_array)
i_array
保存表达式中的所有整数。
更新
如果您已经知道表达式中的所有特殊字符,并且想要将它们全部删除
import re
e_array = re.split('[*/+\-() ]', expression) # all characters here is mult, div, plus, minus, left- right- parathesis and space
i_array = map(int, filter(lambda x: len(x), e_array))
答案 6 :(得分:0)
我将字符串拆分为' + '
字符串,为您提供不在其中的内容:
>>> expression = '123 + 321'
>>> ex = expression.split(' + ')
>>> ex
['123', '321']
>>> int_ex = map(int, ex)
>>> int_ex
[123, 321]
>>> sum(int_ex)
444
这很危险,但您可以使用eval
:
>>> eval('123 + 321')
444
我只是在解析字符串,并对其进行原始计算。