Как токенизировать строку (в которой есть данные о математических вычислениях и числах с плавающей запятой)? - PullRequest
0 голосов
/ 14 мая 2019

Я пытаюсь токенизировать строку (в которой есть данные о математических вычислениях) и создать список.

например,

a = "(3.43 + 2 ^ 2/4)"

function (a) => ['(', '3.43', '+', '2', '^', '2', '/', '4']

Я не хочу использовать внешний импорт (например, nltk).

Проблема, с которой я сталкиваюсь, заключается в сохранении чисел с плавающей запятой без изменений.

Я часами чесал голову и выполнил 2 функции, но проблема возникает, когда она сталкивается с числами с плавающей запятой.

Вот что я сделал:

a = "(3.43 + 2^2 / 4)"
tokens = []

for x in range(1, len(a)-1):
no = []

if a[x] == ".":
    y = x
    no.append(".")

    while is_int(a[y-1]):
        no.insert(0, a[y-1])
        y -= 1

    y = x

    while is_int(a[y+1]):
        no.extend(a[y+1])
        y += 1

    token = "".join(no)
    no = []
    tokens.append(token)

else:
    tokens.append(a[x])

print(tokens)

ВЫВОД:

['3', '3.43', '4', '3', ' ', '+', ' ', '2', '^', '2', ' ', '/', ' ', '4']

Ответы [ 3 ]

2 голосов
/ 14 мая 2019

Вы можете использовать собственный токенизатор Python, который является частью стандартного API:

from tokenize import tokenize
from io import BytesIO

source = "(3.43 + 2^2 / 4)"
tokens = tokenize(BytesIO(source.encode('utf-8')).readline)
non_empty = [t for t in tokens if t.line != '']

for token in non_empty:
    print(token.string)

который напечатает:

(
3.43
+
2
^
2
/
4
)

Подробнее: https://docs.python.org/3/library/tokenize.html

1 голос
/ 14 мая 2019

Обратите внимание, что ваш код не будет работать, если в вашем выражении более 1 цифры. Но вы можете попробовать это:

a = "(3.43 + 22^222 / 4)"
list_a = a[1:-1].split()  # remove first and last paranthesis and split by expression
tokens = []
for val in list_a:
    if '.' in val:  # if number has '.' then convert it to float number.
        tokens.append(float(val))
    elif val.isdigit():  # if it is number then add it to tokens
        tokens.append(val)
    elif len(val)==1:  # if it is math expression then add it to tokens
        tokens.append(val)
    else:  # problem is when you have an expression like: "2^2" - we have to go char by char
        no = []
        for k in val:
            if k.isdigit():
                no.append(k)
            else:
                tokens.append(''.join(no))
                tokens.append(k)
                no = []
        tokens.append(''.join(no))

print(tokens)
1 голос
/ 14 мая 2019

Попробуйте это

a = "(3.43 + 2^2 / 4)"
tokens = []
no = ""

for x in range(0, len(a)):
    # Skip spaces
    if a[x] == " ":
        pass
    # Concatenate digits or '.' to number
    elif a[x].isdigit() or (a[x] == "."):
        no += a[x]
    # Other token: append number if any, and then token
    else:
        if no != "":
            tokens.append(no)
        tokens.append(a[x])
        no = ""

print(tokens)

Выход:

['(', '3.43', '+', '2', '^', '2', '/', '4', ')']

Обратите внимание, это не будет обрабатывать операторы, состоящие более чем из одного символа, такие как ==, **, + =

...