Как проверить определенные вещи в моей строке? - PullRequest
1 голос
/ 09 марта 2020

Мой код должен возвращать 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.

Ответы [ 3 ]

1 голос
/ 09 марта 2020

Обновленный ответ

С момента моего первоначального ответа вы добавили семь новых требований к этому вопросу. Я расстраиваюсь, поскольку думаю, что вам нужно лучше понять суть проблемы, с которой вы столкнулись, прежде чем просить о дополнительной помощи.

Однако я добавлю еще один фрагмент, который может направить вас на правильный путь. Похоже, вы пытаетесь найти правильные математические выражения. Следующий код сделает это:

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, + может повторяться любое количество раз и при этом оставаться действительным математическим выражением, так как оно просто изменяется знак целого числа неоднократно.


Оригинальный ответ

Есть несколько способов приблизиться к этому. Учитывая ваш пример, в вашей логике есть несколько fl aws c:

  • "4.0" - это не цифра c. Numeri c в числовом формате 0-9 или Unicode. Документы здесь
  • Вы проверяете строку по другой строке с ключевым словом in. С вашей первой примерной строкой последовательность «4.0» явно не в последовательности «* ^ - + / ()». Пример того, как это работает:
>>> "4.0" in "asdf4.012345"
True
>>> "4.0" in "0.4"
False

Быстрое исправление, использующее аналогичные логи c, состояло бы в том, чтобы проверять символ за символом, а не слово за словом, и объединять два условия с and. Попробуйте следующий фрагмент:

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 рекомендациям по стилю кода.

0 голосов
/ 09 марта 2020

Добавление нескольких проверок к вашему 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
0 голосов
/ 09 марта 2020

Альтернативой может быть использование регулярного выражения для проверки, содержит ли выражение недопустимые символы; или использовать анализатор строк. Поскольку ваши выражения просты, давайте заставим 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")))
...