Функция Python re.sub (), преобразующая «\ t» в пути к файлу в символ табуляции

1

Я пытаюсь взять файл cpp, который уже был написан, и добавить заголовочные файлы в список включений, используя скрипт python. В настоящее время я создаю строку, в которой есть все входящие в нее элементы, которые я хочу добавить, а затем используя модуль re, который я заменяю на include с моей строкой. У всех включений есть имя "\ t" там, и это вызывает проблемы; вместо того, чтобы печатать строку, как ожидалось (#include "abc\type\GenericTypeMT.h), я получаю #include "abc ype\GenericTypeMT.h. Когда я печатаю свою строку на консоли, она имеет ожидаемую форму, которая заставляет меня думать, что это проблема re.sub, а не проблема с записью в файл. Ниже приведен код.

import re
import string

INCLUDE = "#include \"abc\\type\\"

with open("file.h", "r+") as f:
     a = ""
     b = ""
     for line in file:
         a = a + line
     f.seek(0,0)
     types = open("types.txt", "r+")
     for t in types:
         head = INCLUDE + t.strip() + "MT.h"
         b = b + head + "\n"
     a = re.sub(r'#include "abc\\type\\GenericTypeMT\.h"', b, a)
     types.close()
     print b
     print a
     f.write(a)

Выход для b:

#include "abc\type\GenericTypeMT.h"
#include "abc\type\ServiceTypeMT.h"
#include "abc\type\AnotherTypeMT.h"

Усеченный вывод для a:

/* INCLUDES *********************************/
#include "abc   ype\GenericTypeMT.h"
#include "abc   ype\ServiceTypeMT.h"
#include "abc   ype\AnotherTypeMT.h"

#include <map>
...

Самое близкое к моему вопросу, что я мог найти, - это как записать \t в файл с использованием Python, но это отличается от моей проблемы, поскольку моя, похоже, связана с заменами, выполняемыми регулярным выражением, как показано печатью перед написать.

Теги:

1 ответ

2
Лучший ответ

Функция re.sub() расширяет метасимволы (escape-последовательности) в строке замены. Последовательность символов \t (состоящая из двух символов, \ и t) в вашей заменяемой строке, интерпретируемой модулем re, как escape-последовательность для символа табуляции:

>>> import re
>>> re.sub(r'^.', '\\t', 'foo')
'\too'
>>> print(re.sub(r'^.', '\\t', 'foo'))
    oo

Но если вы использовали функцию для значения замены, то такого расширения не происходит. Обратите внимание, что это включает в себя не обработку заполнителей, вам нужно будет использовать объект соответствия, переданный в функцию, чтобы создать свою собственную логику вставки логического заполнителя.

У вас нет никаких заполнителей в вашем коде, поэтому достаточно создать lambda для создания функции:

a = re.sub(r'#include "abc\\type\\GenericTypeMT\.h"', lambda m: b, a)

Демонстрация на той же искушенной строке образца foo раньше:

>>> re.sub(r'^.', lambda m: '\\t', 'foo')
'\\too'
>>> print(re.sub(r'^.', lambda m: '\\t', 'foo'))
\too

Функция re.escape(), к сожалению, слишком re.escape(), добавляя \ обратную косую черту ко многим другим символам, а не только заменяющие метасимволы; у вас будет намного больше обратных косых черт, чем вы начали.

Обратите внимание, что, поскольку на вашей подстановке фактически не выполняется сопоставление шаблонов, вы можете просто использовать str.replace() для выполнения задания:

a = a.replace(r'#include "abc\type\GenericTypeMT.h"', b)

\ И . символы больше не являются метасимволом в регулярном выражении, поэтому им также не требуется экранирование.

  • 0
    Это \#include\ \"abc\type\GenericTypeMT\.h\"\ проблему \t , но также печатает все косые черты: \#include\ \"abc\type\GenericTypeMT\.h\"\ . Я полагаю, я мог бы вернуться туда, где я объявил INCLUDE и сделать его необработанной строкой?
  • 0
    @SCE: Ах, я вижу, что происходит. re.escape() слишком жадный, re.escape() .
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню