【问题标题】:How to check for certain things in my string?如何检查我的字符串中的某些内容?
【发布时间】:2020-03-09 19:18:46
【问题描述】:

我的代码应该返回 None 如果字符串:

包含不受支持的运算符或非数字。支持的运算符有:**、*、^、-、+、/、(、)

示例

“4.0 + 2”有效

“3.88327 - $3.4”是无效(因为“$”)

“a + 24”无效(因为“a”)

“2+6”有效

“4+/3”无效(因为“+/”是两个相邻的运算符)

“4**-3”有效

我该怎么做?

这是我的代码:

def checkvalid(string1):
    temp = string1.split()
    for i in len(temp):
        if i in "*^-+/()":
            return None
        if not i.isnumeric():
            return None

    return string1

但这并不总是有效。它只适用于像“22 66”这样的常规整数 -> 这有效,它返回字符串,但似乎没有其他工作,它总是返回 None。

【问题讨论】:

  • 当前代码将失败,因为 '4.0' in '*^+/() 如果总是 False'4.0'.isnumeric() 总是 False
  • for i in len(temp): 循环遍历 indexes,即0 1 2 3 等。大概你想检查temp[i],而不是i 本身。
  • 你为什么还要费心拆分字符串?直接遍历字符串中的字符是非常自然的:for ch in string1:
  • @JohnGordon cuz 如果我遍历字符串的每个字符,我怎么知道它是否是浮点数

标签: python string list


【解决方案1】:

更新答案

自从我最初的回答以来,您已经向这个问题添加了七个新要求。我不参与了,因为我认为您需要在寻求更多帮助之前更好地了解您所面临的问题的范围。

但是,我将再抛出一个可能会让您走上正确道路的 sn-p,因为您似乎正在尝试找到有效的数学表达式。以下代码将执行此操作:

def check_valid(data):
    errors = (SyntaxError, NameError)
    try:
        eval(data)
    except errors:
        for i in data.split():
            try:
                eval(i)
            except errors:
                return None
    return data

test = ["4++2", "4+-2", "4.0 + 2", "3.88327 - $3.4", "a + 24", "2+6", "4+/3"]

for t in test:
    try:
        assert check_valid(t)
        print(f"{t} valid")
    except AssertionError:
        print(f"{t} not valid")

输出

4++2 valid
4+-2 valid
4.0 + 2 valid
3.88327 - $3.4 not valid
a + 24 not valid
2+6 valid
4+/3 not valid

在 Python 中,+ 可以重复任意次数,并且仍然是有效的数学表达式,因为它只是重复更改整数的符号。


原答案

有很多方法可以解决这个问题。鉴于您的示例,您的逻辑存在一些缺陷:

  • “4.0”不是数字。数字是 0-9 或 unicode 数字。 Docs here
  • 您正在使用in 关键字检查一个字符串与另一个字符串。对于您的第一个示例字符串,序列“4.0”显然不在序列“*^-+/()”中。工作原理示例:
>>> "4.0" in "asdf4.012345"
True
>>> "4.0" in "0.4"
False

使用类似逻辑的快速解决方法是逐个字符而不是逐个单词检查,并将两个条件与and 结合起来。试试下面的 sn-p:

def check_valid(data):
    for word in data.split():
        for character in word:
            if character not in "*^-+/()." and not character.isnumeric():
                return None

    return data

test = ["4.0 + 2", "3.88327 - $3.4", "a + 24", "22 66", "2+6"]

for t in test:
    print(f"Test: {check_valid(t)}")

输出

Test: 4.0 + 2
Test: None
Test: None
Test: 22 66
Test: 2+6

注意:我更改了一些名称以更紧密地遵循 Python 代码样式最佳实践。

【讨论】:

  • 这假设与您的代码完全相同。除非给出分隔符,否则 str.split() 方法会在空格上拆分。也许您应该用更多信息重申您的问题,因为鉴于要求,此代码完全按照您的要求执行。
  • 你真的尝试过代码吗? 2+6 在这里也有效。
  • 我明白了。到目前为止,您提到的示例不在您最初的问题中。同样,最好说明您要解决的问题,而不是提供一个很小的数据集进行检查。例如,您似乎正在尝试在此处检查有效的数学表达式。
  • 此时我要退出了。我怀疑无论任何人根据您的要求提出什么,您仍然会发现漏洞,因为您不了解问题的全部范围并且没有很好地传达它。我将再添加一个示例,它可能会让您走上正确的道路。抱歉,我无法提供更多帮助!
  • 不,这一切都很好,兄弟,你帮了我很多,会接受你的回答,因为这是迄今为止最好的一个。它defintley帮助我走上了轨道。谢谢
【解决方案2】:

向您的 eval 添加一些检查可以使其更安全一些,但并不理想。

import re

def checkvalid(string1):
    string1 = string1.replace(" ", "")
    checkStatements = ["++", "-+", "---"]
    checkOut = [x for x in checkStatements if x not in string1]
    # If you require anything further characters to be avoided place them in the regex
    if re.match('[a-zA-Z]', string1) or len(checkOut) != len(checkStatements):
        return False
    else:
        try:
            output = eval(string1)
            if isinstance(output, float) or isinstance(output, int):
                return True
            else:
                return False
        except:
            return False

【讨论】:

  • 因为它将第二个变量标记为正数,但如果不允许这样做,是否允许诸如“**”之类的运算符?比如2**2 = 4?
  • 更新为允许 ** 但不允许 ++
【解决方案3】:

另一种方法可能是使用正则表达式来检查表达式是否包含无效字符;或使用字符串解析器。 因为你的表达很简单,让我们用python来做我们的工作

def check_valid(expression: str):
try:
    eval(expression) # Execute the expression; If the expression is valid, return the result of the evaluation; if is invalid; raise exception
    return True
except Exception as _:
    return False

if __name__ == '__main__':
    print("{expression}: {validity}".format(expression="4.0 + 2", validity=check_valid("4.0 + 2")))
    print("{expression}: {validity}".format(expression="3.88327 - $3.4", validity=check_valid("3.88327 - $3.4")))
    print("{expression}: {validity}".format(expression="a + 24", validity=check_valid("a + 24")))
    print("{expression}: {validity}".format(expression="2+6", validity=check_valid("2+6")))

【讨论】:

  • a=10;b=eval('a+10') 现在 b 将是 11。不要使用 eval。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多