замена некоторых неизвестных слов в строке

#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 в оригинале (можно увидеть в правом верхнем углу в ссылках).

Вы можете увидеть новый шаблон в действии здесь.