Поиск совпадений с шаблонами в файлах заголовков C

poisk sovpadenij s shablonami v fajlah zagolovkov c Текст и язык

В завершение обратимся к более практичному примеру: сценарий в примере 19.6 объединяет представленные выше операторы шаблонов для решения более практичной задачи. С помощью регулярных выражений он отыскивает строки #define и #include в файлах заголовков на языке С и извлекает их составляющие. Обобщенность этих шаблонов позволяет обнаруживать целый ряд строк; группы в шаблонах (части, заключенные в круглые скобки) используются для извлечения из строк соответствующих подстрок после нахождения соответствия.

Пример 19.6. PP4E\Lang\cheader.py

"Сканирует файлы заголовков C и извлекает части инструкций #define и #include"

import sys, re

pattDefine = re.compile( # компилировать в объект шаблона

‘~#[\t ]*define[\t ]+(\w+)[\t ]*(.*)’) # "# define xxx yyy…"

# \w аналог [a-zA-Z0-9_]

pattInclude = re.compile(

‘~#[\t ]*include[\t ]+[<"]([\w\./]+)’) # "# include <xxx>…"

def scan(fileobj):

count = 0

for line in fileobj: # сканировать построчно: итератор

count += 1

matchobj = pattDefine.match(line) # None, если совпадение не найдено if matchobj:

name = matchobj.group(1) # подстроки для групп (…)

body = matchobj.group(2)

print(count, ‘defined’, name, ‘=’, body.strip()) continue

matchobj = pattInclude.match(line)

if matchobj:

start, stop = matchobj.span(1) # start/stop смещения (…) filename = line[start:stop] # вырезать из строки print(count, ‘include’, filename) # то же,

# что и matchobj.group(1)

if len(sys.argv) == 1:

scan(sys.stdin) # без аргументов: читать stdin

else:

scan(open(sys.argv[1], ‘r’)) # аргумент: имя файла

Для проверки просканируем с помощью этого сценария текстовый файл, представленный в примере 19.7.

Пример 19.7. PP4E\Lang\test.h

#ifndef TEST_H

#define TEST_H

#include <stdio.h>

#include <lib/spam.h>

#   include "Python.h"

#define DEBUG

#define HELLO ‘hello regex world’

#   define SPAM 1234

#   define EGGS sunny + side + up

#   define ADDER(arg) 123 + arg

#endif

Обратите внимание на пробелы после # в некоторых строках — регулярные выражения достаточно гибки, чтобы учитывать такие отклонения от нормы. Ниже показан результат работы этого сценария — он выбирает строки #include и #define и их части. Для каждой найденной строки в файле выводится ее номер, тип и найденные подстроки:

C:\\PP4E\Lang> python cheader.py test.h

2  defined TEST_H =

4  include stdio.h

5  include lib/spam.h

6  include Python.h

8  defined DEBUG =

9  defined HELLO = ‘hello regex world’

10  defined SPAM = 1234

12  defined EGGS = sunny + side + up

13  defined ADDER = (arg) 123 + arg

Еще один пример использования регулярных выражений можно найти в файле pygrep1.py в пакете примеров к книге. Он реализует простую утилиту «grep» поиска строк в файлах по шаблону, но не вошел в книгу из-за экономии места. Как будет показано далее, регулярные выражения иногда можно использовать для извлечения информации из текстовых файлов в формате XML и HTML, что является темой следующего раздела.

Использованная литература:

Марк Лутц — Программирование на Python, 4-е издание, II том, 2011

Каталог сайтов Всего.ру
Оцените статью
Секреты программирования
Добавить комментарий