【问题标题】:Python: Check if string is a number WITHOUT using regex or try-exceptPython:检查字符串是否是一个数字,而不使用正则表达式或 try-except
【发布时间】:2014-05-19 21:05:33
【问题描述】:

在这里的第一篇文章,尝试搜索,但每个人的答案都是“使用正则表达式”。希望我能很好地符合该网站的其他标准。

刚刚学习了python和一个硬件分配是创建一个函数来测试一个字符串是否是一个数字。使用异常很容易。我们被要求提出另一种测试方法,提示是使用正则表达式。同样,很简单。

在我自己尝试更好地了解 python 的过程中,我想在没有正则表达式的情况下做同样的事情,并希望任何可以计算为数字的字符串的附加功能都返回 True,例如,'5++ -3j ++ 4.j-6.1' 应该返回 True,但 'j32' 会返回 False。

我遇到了一些问题:例如,'5j' 是 False,但 '+5j' 和 '+=5j' 都是 True。此外,函数中的打印语句只是为了让我可以看到计算机在各个阶段看到的内容。谢谢!

编辑:我意识到变量 j 与复数 j 的不幸放置,但引号应该清楚地表明所指的是哪个 j。

编辑:正如@georg 所指出的,我正在测试一个字符串是否是一个数字表达式,如果它的计算结果是一个数字

def is_itnumber(el):
    '''Identifies if a string can be converted to a number, in an unuseful way!'''
    mast=[]
    el_p=el.split(sep='+')
    for el_m in el_p:
        n=el_m.split(sep='-')
        mast.extend(n)
    for l in mast:
        if l=='': mast.remove(l)
        print(mast)
        for j in range(len(l)):
            print( l[j])
            if l[j]==',':
                if j not in range(len(l)-3):
                    return False
                elif (l[j+1].isdigit()==0 or l[j+2].isdigit()==0 or l[j+3].isdigit()==0):
                    return False
            elif l[j]=='j':
                if j != len(l):
                    return False
            elif l[j]=='.':
                for x in range(len(l)):
                    if l[x]=='.' and x!=j:
                        return False
            elif l[j].isdigit()==0:
                    return False
    else:
        return True

【问题讨论】:

  • 5++-3j + + 4.j-6.1 是什么鬼数字????????
  • 我看不到你帖子中的“5j”或任何其他东西是一个数字。你能解释一下吗?
  • @Adam Smith,希望 '5++-3j + + 4.j-6.1' 返回 True,因为 '5++-3j + + 4.j-6.1'='-1.1+ 1j' 作为复数。
  • @s16h 复数应该包括在内,我正在寻找完整的通用性。
  • @AdamSmith 尝试将4.j 放入解释器。

标签: python regex python-3.x


【解决方案1】:

我不知道5++-3j + + 4.j-6.1 是什么。但是如果你想测试字符串s中的整数:

all(['0' <= c <= '9' for c in s])

您可以展开浮点数:

all(['0' <= c <= '9' for c in s]) and s.count('.') <= 1

除此之外,您基本上是在实现一个自定义的正则表达式引擎,该引擎可能存在错误并且性能不佳。

编辑:我的立场是正确的:

>>> 5++-3j + + 4.j-6.1 
(-1.0999999999999996+1j)

我唯一的另一个想法是使用ast.parse

【讨论】:

  • 感谢编辑,我会检查 ast.parse,我现在不知道它是什么。
【解决方案2】:

我猜你的意思是“一个数字表达式”,而不仅仅是一个“数字”。 5++-3j + + 4.j-6.1 绝对不是数字,但它是一个有效的“数字表达式”。由于这是一种语言,您需要parser 来验证它。幸运的是,python 提供了一种解析自身的方法:ast module。在不声明完整性的情况下,这里是一个可能实现的草图:

import ast

class CheckNumeric(ast.NodeVisitor):
    def validate(self, expr):
        self.valid = True
        self.visit(ast.parse(expr))
        return self.valid

    def check(self, node):
        operators = [ast.Add, ast.Sub, ast.Mult, ast.Div, ast.UAdd, ast.USub]
        if type(node) in [ast.BinOp, ast.UnaryOp]:
            return type(node.op) in operators
        return type(node) in operators + [ast.Module, ast.Expr, ast.Num]

    def generic_visit(self, node):
        if not self.check(node):
            self.valid = False
        if self.valid:
            ast.NodeVisitor.generic_visit(self, node)

这个类应该接受数字表达式并拒绝所有其他的:

print CheckNumeric().validate('5++-3j + + 4.j-6.1') # True
print CheckNumeric().validate('j32') # False
print CheckNumeric().validate('foo((((') # SyntaxError

【讨论】:

  • 我把帖子修改为数字表示,谢谢!目前,这个实现超出了我的想象。尽管我经常在 Python 代码中看到“自我”论点,但我不理解它。我想我们很快就会了解课程,希望您的解决方案能在短期内对我更有意义。
猜你喜欢
  • 1970-01-01
  • 2014-03-30
  • 1970-01-01
  • 2013-01-01
  • 2017-02-09
  • 1970-01-01
  • 2020-01-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多