2

假设我有一个字符串如下:expression = '123 + 321'.

我正在逐个字符地遍历字符串,如下所示for p in expression:我正在检查是否p是使用p.isdigit(). 如果p是一个数字,我想抓住整个数字(所以抓住123and 321,而不仅仅是p最初会是1)。

我怎样才能在 Python 中做到这一点?

在 C(来自 C 背景)中,等价于:

int x = 0;
sscanf(p, "%d", &x);
// the full number is now in x

编辑:

基本上,我接受来自接受正整数、+、-、*、/ 以及括号的用户的数学表达式:'(' 和 ')'。我正在逐个字符地遍历字符串,我需要能够确定该字符是否为数字。使用isdigit(),我可以。但是,如果它是一个数字,我需要获取整个数字。怎么可能呢?

4

7 回答 7

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']
于 2012-09-08T00:42:14.047 回答
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']

查看其他答案,我发现这与jamylakgroupby解决方案没有什么不同。如果您不想丢弃多余的符号,我建议您这样做。但是,如果您确实想丢弃它们,我认为这会更简单一些。

于 2012-09-08T00:59:36.767 回答
1

虽然我不熟悉sscanf,但我不是 C 开发人员,但看起来它使用格式字符串的方式与我使用 pythonre模块的方式没有什么不同。像这样的东西:

import re

nums = re.compile('\d+')
found = nums.findall('123 + 321')
# if you know you're only looking for two values.
left, right = found
于 2012-09-08T00:44:59.433 回答
1

Python 文档包含一个关于simulatingscanf的部分,它让您了解如何使用正则表达式来模拟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 内置的正则表达式匹配迭代方法:

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因为您不必在再次迭代它们以将它们转换为整数之前制作所有字符串的列表。

于 2012-09-08T00:54:07.583 回答
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
于 2012-09-08T07:38:28.593 回答
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))
于 2012-09-08T00:39:16.453 回答
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

我只是在尝试解析字符串,并对其进行原始计算。

于 2012-09-08T00:41:25.270 回答