Использование библиотеки PCRE для работы с регулярными выражениями
Использование библиотеки PCRE для работы с регулярными выражениями
В предыдущей статье я упомянул об альтернативных инструментах для работы с регулярными выражениями. Наиболее известное из них - кроссплатформенная библиотека PCRE (Perl Compatible Regular Expressions). Библиотека абсолютно бесплатная, разрабатывается аж с 1997 года и используется во множестве серьезных проектов. Сегодня я покажу примеры использования этой библиотеки в приложениях на Ассемблере под Windows.
Готовые dll разных версий можно скачать здесь, но если есть навыки и желание, то, конечно, лучше самостоятельно собрать библиотеку из исходников с офсайта.
Теперь переходим к программированию. Для тестов возьмем уже знакомую вам строку и паттерн для извлечения адресов электронной почты.
Code (Assembler) : Убрать нумерацию
- szPattern db '(([-_a-z0-9\.]+)@([-_a-z0-9\.]+\.([a-z]+)))',0
- szTest db 'Please email me to mymail@gmail.com '
- db 'or nospam@mail.com.ru. I am waiting!',0
Code (Assembler) : Убрать нумерацию
- ; Подготовить регулярное выражение
- invoke pcre_compile,szPattern,0,errBuff,errOff,NULL
- mov [re],eax
- ; Предобработка регулярного выражения
- PCRE_STUDY_JIT_COMPILE = 0x0001
- invoke pcre_study,[re],PCRE_STUDY_JIT_COMPILE,errBuff
- mov [re_extra],eax
Code (Assembler) : Убрать нумерацию
- ; Длина исходной строки
- invoke lstrlen,szTest
- mov [dLen],eax
- ; Начальная позиция поиска в строке
- mov [offs],0
- ; Найти соответствие регулярному выражению
- invoke pcre_exec,[re],[re_extra],szTest,[dLen],\
- [offs],0,matches,MAX_CAPTURES
- ; Количество найденных совпадений
- mov [rc],eax
Если найдено хоть одно совпадение, то функция возвращает их количество, а массив matches заполняется парами DWORD'ов. В каждой паре первый DWORD обозначает начальную позицию найденного паттерна или субпаттерна относительно начала проверяемой строки, второй DWORD - конечную позицию. Перебирая пары по очереди, получаем все найденные результаты. Более полный код обработки регулярного выражения с субпаттернами будет следующим:
Code (Assembler) : Убрать нумерацию
- ; Начальная позиция поиска в строке
- mov [offs],0
- ; Длина исходной строки
- invoke lstrlen,szTest
- mov [dLen],eax
- loc_loop:
- ; Найти соответствие регулярному выражению
- invoke pcre_exec,[re],[re_extra],szTest,[dLen],\
- [offs],0,matches,MAX_CAPTURES
- ; Количество найденных совпадений
- mov [rc],eax
- ; Возникла ошибка?
- or eax,eax
- js loc_not_found
- ; Хоть одно соответствие найдено?
- jnz loc_found
- loc_not_found:
- ; Больше ничего не найдено
- jmp loc_done
- loc_found:
- ; Смещение конца найденного паттерна
- mov ecx,[matches+4]
- ; Новое начало поиска
- mov [offs],ecx
- ; Смещение начала найденного паттерна
- mov esi,[matches]
- ; Вычислить длину стрки
- sub ecx,esi
- or ecx,ecx
- jz loc_next
- ; Выделить найденную строку
- add esi,szTest
- mov edi,szMatch
- rep movsb
- xor eax,eax
- stosb
- ; szMatch -> строка найденного паттерна
- ; Перебрать все субпаттерны
- xor ebx,ebx
- loc_sub:
- ; Смещение конца найденного паттерна
- mov ecx,[matches+8+ebx*8+4]
- ; Смещение начала найденного паттерна
- mov esi,[matches+8+ebx*8]
- ; Вычислить длину стрки
- sub ecx,esi
- or ecx,ecx
- jz loc_next
- ; Выделить найденную подстроку
- add esi,szTest
- mov edi,szMatch
- rep movsb
- xor eax,eax
- stosb
- ; szMatch -> строка субпаттерна
- inc ebx
- cmp ebx,[rc]
- jb loc_sub
- loc_next:
- jmp loc_loop
- loc_done:
В приложении пример программы с исходным текстом, которая выполняет поиск по строке с использованием регулярных выражений и библиотеки PCRE.
Просмотров: 117 | Комментариев: 0
Метки: Assembler, регулярные выражения
Комментарии
Отзывы посетителей сайта о статье
Комментариeв нет
Добавить комментарий
Заполните форму для добавления комментария