Удалить ведущие нули из сложной исполняемой строки python

Я работаю с Grammatical Evolution (GE) на Python 3.7. Моя грамматика генерирует исполняемые строки в формате:

np.where(<variable> <comparison_sign> <constant>, (<probability1>), (<probability2>))

Тем не менее, строка может стать довольно сложной, с несколькими цепочками np.where .

<constant> в некоторых случаях содержит ведущие нули, из-за чего исполняемая строка выдает ошибки. GE должен генерировать выражения, содержащие ведущие нули, однако мне нужно обнаружить и удалить их. Пример возможного решения, содержащего ведущие нули:

"np.where(x < 02, np.where(x > 01.5025, (0.9), (0.5)), (1))"

Проблема:

  • Есть два типа чисел, содержащих ведущие нули: int и float.
  • Предположим, что я обнаружил 02 в строке. Если я заменю все вхождения в строке с 02 на 2, число с плавающей точкой 01.5025 также изменится на 01.525, чего не может быть.

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

try:
  _ = eval(expression)
except SyntaxError:
  new_expression = fix_expressions(expression)

Мне нужна помощь в создании функции fix_expressions Python.


person Pedro Pereira    schedule 14.11.2020    source источник
comment
это решение для вас: stackoverflow.com/questions/13142347/?   -  person Alexander Riedel    schedule 14.11.2020
comment
Частично. Не хватает двух вещей: обнаруживать только числа с ведущими нулями и заменять только те вхождения, не изменяя другие числа, которые содержат их частично. Пример: замена 02 на 2 без изменения 0,025 на 0,25.   -  person Pedro Pereira    schedule 14.11.2020


Ответы (2)


Вы можете попытаться придумать регулярное выражение для чисел с ведущими нулями, а затем заменить ведущие нули.

import re

def remove_leading_zeros(string):
    return re.sub(r'([^\.^\d])0+(\d)', r'\1\2', string)

print(remove_leading_zeros("np.where(x < 02, np.where(x > 01.5025, (0.9), (0.5)), (1))"))

# output: np.where(x < 2, np.where(x > 1.5025, (0.9), (0.5)), (1))

Функция remove_leading_zeros в основном находит все вхождения [^\.^\d]0+\d и удаляет нули. [^\.^\d]0+\d переводится не как число и не как точка, за которой следует хотя бы один ноль, за которым следует число. Скобки (, ) в регулярном выражении обозначают группы захвата, которые используется для сохранения символа перед начальными нулями и числа после.

person upe    schedule 14.11.2020
comment
Идеально! Спасибо большое :) - person Pedro Pereira; 14.11.2020

Вы можете удалить ведущие 0 в строке, используя .lstrip()

str_num = "02.02025"

print("Initial string: %s \n" % str_num)

str_num = str_num.lstrip("0")

print("Removing leading 0's with lstrip(): %s" % str_num)
person BWallDev    schedule 14.11.2020
comment
Это применимо к случаям, когда у меня есть строка, содержащая только числа. Обратите внимание, что мои строковые выражения более сложны. Даже если я могу обнаружить только числа, содержащие ведущие нули, как я могу заменить их во всем выражении, не затрагивая другие числа? Пример: замена 02 на 2 без изменения 0,025 на 0,25. - person Pedro Pereira; 14.11.2020
comment
Если ваша цель состоит в том, чтобы удалить ведущие 0, lstrip() не возражает, если строка состоит только из цифр или из цифр и символов. если str_num был равен 02.025, он вернет 2.025 - person BWallDev; 14.11.2020
comment
Я попробовал: np.where(x ‹ 02, np.where(x › 01,5025, (0,9), (0,5)), (1)).lstrip(0) и получил: np.where(x ‹ 02, np .where(x › 01.5025, (0.9), (0.5)), (1)) Так что либо я не могу объяснить свою проблему, либо не понимаю вашего предложения... - person Pedro Pereira; 14.11.2020
comment
строка, представляющая <constant>, — это то, для чего вы хотели бы использовать функцию lstrip(0). Однако, возможно, я неправильно понимаю, о чем вы спрашиваете. - person BWallDev; 14.11.2020
comment
Моя проблема заключается в том, чтобы обнаружить только те вхождения во всей строке и заменить только их. Пример: я обнаруживаю 02, применяю lstrip() и заменяю его во всей строке на str.replace("02", "2"). При этом число 0,025 также будет заменено на 0,25, поскольку 02 является подстрокой 0,025. Верно? - person Pedro Pereira; 14.11.2020
comment
Скопируйте код, который я указал выше в своем ответе, в новый файл, запустите его и посмотрите результаты вывода. Я не уверен, как выглядит ваш код, поэтому я не уверен, как все устроено. Может быть, это не поможет вашим обстоятельствам - person BWallDev; 14.11.2020
comment
re.sub(r'([^\.^\d])0+(\d)', r'\1\2', string) это решило мою проблему. В любом случае, спасибо! - person Pedro Pereira; 14.11.2020