2009-04-07 6 views
5

Мне любопытно, кто-нибудь знает хороший способ сделать регулярное выражение в C? Единственный способ, о котором я могу думать, - это через Flex. Это единственный способ или есть лучший способ?Регулярные выражения в C

Спасибо!

ответ

13

Мм ... Лучший способ это

#include <regex.h> 

Это является POSIX standard API для регулярных выражений.

Для систем, отличных от POSIX, использование вашей собственной альтернативы - один из основных механизмов регулярного выражения, который не так сложно выполнить. Я уверен, что есть готовые решения тоже, я его не уложил.

Подумайте об этом, я думаю, glib имеет один.

+1

не записывайте собственный двигатель регулярных выражений. это ужасный совет. –

0

this article Возможно, поможет? Он показывает вам, как использовать регулярные выражения, определенные в regex.h.

Да, это не просто регулярное выражение POSIX замечательно у них есть все это, так что я задавался вопросом почему они не в C? Ну, я нашел ответ, и я получил счастлив, они есть, и вот как использовать им

11

В зависимости от того, что говор вы ищете, и какую платформу вы находитесь на:

  • POSIX регулярные выражения, вероятно, будут в стандартной библиотеке C - см. <regex.h> и regcomp, regerror, regexec, regfree.
  • libPCRE обеспечивает большую часть расширенной регулярных выражений в Perl имеется
  • бойкий имеет GRegex
  • Henry Spencer's Tcl Regex library.

Генри Спенсер также сделал еще один regex library, используемый в текущих версиях TCL и PostgreSQL. Это интересно, потому что это гибридная реализация NFA/DFA.

Regexes, которые принимают одни и те же строки несколькими способами (например, a * a?), По сути требуют NFA. Обычная реализация моделирует NFA как DFA с использованием обратного отсчета, которая может быть равной O (длина 2 × (вход)) для особо вырожденного шаблона. Но простая рекурсивная реализация может быть дополнена захватом, обратными ссылками, обратными вызовами кода и всеми обычными «дополнительными» функциями, которые предлагают многие языки помимо тестирования на совпадения.

Подход «NFA» отслеживает множество текущих состояний и обновляет их все с каждым входящим символом (см. Запись Росса Кокса Thompson NFA regexes для получения дополнительных пояснений). Этот подход - O (input.length * pattern.length), который выполняется быстрее - в худшем случае - но не может выполнять backrefs или capture, так как он не отслеживает , как он попал в состояние.

Подход Спенсера представляет собой гибрид, который компилирует некоторые части шаблона подходу NFA и использует обратное отслеживание только там, где это необходимо для захватов, которые были фактически запрошены. Это часто является существенной победой (см. TCL position in the regex-dna shootout).

+0

В интерпретации регулярного выражения в стиле NFA используется обратное отслеживание, тогда как стиль DFA - нет? – Vatine

+0

Regexes, которые могут принимать одни и те же строки несколькими способами, по сути нуждаются в NFA. Обычной реализацией в качестве возврата DFA + является O (2^n). Подход «NFA» поддерживает несколько текущих состояний и обновляет все их с каждым входящим символом (O (n * m). См. Http://swtch.com/~rsc/regexp/regexp1.html – puetzk

1

Совершенно иной подход попробовать Parsing Expression Grammar (PEG). PEG приходит к проблеме соответствия шаблонов с точки зрения анализатора и может даже использовать несколько правил, которые образуют полную грамматику. Это позволяет писать выражения, соответствующие сбалансированным скобкам, которые в большинстве случаев довольно трудно выразить в большинстве диалектов regexp.

Хотя PEGs являются относительно новыми, там должно быть несколько реализаций там, которые могут использоваться с C.

Реализация PEG Я лично использовал это LPeg. Он аккуратно связан с Луа, и по совпадению был написан одним из главных авторов Луа, Роберто Иерусульским. Он обеспечивает полную реализацию PEG, а также включает адаптер, который переводит регулярное выражение в эквивалентный PEG для выполнения.

Ссылка на ядро ​​Lua на программу C, чтобы получить доступ к LPEG, может показаться излишним, но это действительно не так сложно сделать, даже если вы не планируете использовать Lua для других целей.

Смежные вопросы