#python
#python
Вопрос:
Я ищу более элегантное решение для замены некоторых заранее неизвестных слов в строке, за исключением not
, and
и or
:
Только в качестве примера ниже, но может быть любым, но всегда будет оцениваться с помощью eval())
ввод: (DEFINE_A or not(DEFINE_B and not (DEFINE_C))) and DEFINE_A
вывод: (self.DEFINE_A or not(self.DEFINE_B and not (self.DEFINE_C))) and self.DEFINE_A
Я создал решение, но оно выглядит как-то странно. Есть ли более чистый способ?
s = '(DEFINE_A or not(DEFINE_B and not (DEFINE_C))) and DEFINE_A'
words = re.findall(r'[w] |[()]*|[ ]*', s)
for index, word in enumerate(words):
w = re.findall('^[a-zA-Z_]
Будет печатать правильно:
(self.DEFINE_A or not(self.DEFINE_B and not (self.DEFINE_C))) and self.DEFINE_A
Комментарии:
1. Всегда ли переменные будут иметь форму
DEFINE_x
?2. Нет, они этого не делают. например, может быть 'LOGGING__ENABLED' или 'CONFIGURE_KEYBOARD_PRESENT'
3. Просто хотел убедиться, что мой ответ может быть более конкретным, но я думаю, что нет... Всегда ли они будут написаны с заглавной буквы?
4. Да, они всегда будут с заглавной буквы.
5. Затем посмотрите мою правку для упрощенной, более эффективной версии 🙂
Ответ №1:
Прежде всего, вы можете сопоставлять только слова, используя простой w
. Затем, используя негативный взгляд, вы можете исключить те, которые вам не нужны. Теперь все, что осталось сделать, это использовать re.sub
непосредственно с этим шаблоном:
s = '(DEFINE_A or not(DEFINE_B and not (DEFINE_C))) and DEFINE_A'
new = re.sub(r"(?!and|not|or)b(w )", r"self.1", s)
print(new)
Что даст:
(self.DEFINE_A or not(self.DEFINE_B and not (self.DEFINE_C))) and self.DEFINE_A
Вы можете протестировать и посмотреть, как работает это регулярное выражение здесь.
Если имена ваших "переменных" всегда будут написаны с заглавной буквы, это немного упрощает шаблон и делает его намного более эффективным. Просто используйте:
new = re.sub(r"([A-Zd_] )", r"self.1", s)
Это не только более простой шаблон (для удобства чтения), но и гораздо более эффективный. В этом примере требуется всего 70 шагов по сравнению с 196 в оригинале (можно увидеть в правом верхнем углу в ссылках).
Вы можете увидеть новый шаблон в действии здесь.
, word)
if w and w[0] not in ['and','or','not']:
z = 'self.' w[0]
words[index] = z
new = ''.join(str(x) for x in words)
print(new)
Будет печатать правильно:
Комментарии:
1. Всегда ли переменные будут иметь форму
DEFINE_x
?2. Нет, они этого не делают. например, может быть ‘LOGGING__ENABLED’ или ‘CONFIGURE_KEYBOARD_PRESENT’
3. Просто хотел убедиться, что мой ответ может быть более конкретным, но я думаю, что нет… Всегда ли они будут написаны с заглавной буквы?
4. Да, они всегда будут с заглавной буквы.
5. Затем посмотрите мою правку для упрощенной, более эффективной версии 🙂
Ответ №1:
Прежде всего, вы можете сопоставлять только слова, используя простой w
. Затем, используя негативный взгляд, вы можете исключить те, которые вам не нужны. Теперь все, что осталось сделать, это использовать re.sub
непосредственно с этим шаблоном:
Что даст:
Вы можете протестировать и посмотреть, как работает это регулярное выражение здесь.
Если имена ваших «переменных» всегда будут написаны с заглавной буквы, это немного упрощает шаблон и делает его намного более эффективным. Просто используйте:
Это не только более простой шаблон (для удобства чтения), но и гораздо более эффективный. В этом примере требуется всего 70 шагов по сравнению с 196 в оригинале (можно увидеть в правом верхнем углу в ссылках).
Вы можете увидеть новый шаблон в действии здесь.