Подтвердить что ты не робот

PCRE в Haskell - что, где, как?

Я искал некоторую документацию или учебник по регулярным выражениям Haskell на века. Нет никакой полезной информации на странице HaskellWiki. Он просто дает загадочное сообщение:

Documentation
Coming soonish.

Есть короткий пост в блоге, который я нашел довольно полезным, однако он касается только регулярных выражений Posix, а не PCRE.

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

Моя проблема в том, что я не знаю, с чего начать с PCRE в Haskell. Я загрузил regex-pcre-builtin с помощью cabal, но мне нужен пример простой программы соответствия, чтобы помочь мне начать работу.

  • Возможно ли реализовать многострочное сопоставление?
  • Могу ли я получить спички в этом формате: [(MatchOffset,MatchLength)]?
  • Какие еще форматы я могу получить в матчах?

Большое спасибо за любую помощь!

4b9b3361

Ответ 1

Хорошо, я написал большую часть вики-страницы и, возможно, написал "Coming soonish". Пакет regex-pcre представлял собой мою упаковку PCRE с использованием интерфейса regex-base, где regex-base используется как интерфейс для нескольких очень разных баз данных механизма регулярных выражений. У пакета Doncewart pcre-light нет этого слоя абстракции и, следовательно, намного меньше.

Сообщение в блоге Text.Regex.Posix использует мой пакет regex-posix, который также находится поверх базы regex. Таким образом, использование regex-pcre будет очень похоже на это сообщение в блоге, за исключением того, что параметры компиляции и выполнения PCRE различаются.

Для настройки regex-pcre Модуль Text.Regex.PCRE.Wrap имеет необходимые вам константы. Используйте makeRegexOptsM из regex-base, чтобы указать параметры.

Ответ 2

Есть два основных параметра, когда вы хотите использовать регулярные выражения типа PCRE в Haskell:

  • regex-pcre использует тот же интерфейс, который описан в этом сообщении в блоге (а также в RWH, как я думаю, расширенная версия этого блога); это может быть дополнительно расширено pcre-less. regex-pcre-builtin, кажется, является предварительным выпуском этого снимка и, вероятно, не должен использоваться.

  • pcre-light - привязки к библиотеке PCRE. Он не предоставляет типы возвращаемых результатов, а только все сопоставления (если есть). Тем не менее, пакет pcre-light-extras предоставляет класс MatchResult, для которого вы могли бы предоставить такой экземпляр. Это можно улучшить, используя regexqq, который позволяет использовать квазицитирование, чтобы гарантировать, что ваш тип шаблона регулярного выражения; однако он не работает с GHC-7 (и если кто-то не возьмет его на себя, он не будет).

Итак, если вы идете с regex-pcre:

  • В соответствии с ответом this да.

  • Я так думаю, используя тип MatchArray (он возвращает массив, из которого вы можете получить список).

  • Смотрите здесь для всех возможных результатов из регулярного выражения.

Ответ 3

Там также regex-applicative, который я написал.

Идея состоит в том, что вы можете назначить некоторый смысл каждой части регулярного выражения, а затем составить их, точно так же, как вы пишете парсеры с использованием Parsec.

Вот пример - простой синтаксический анализ URL.

import Text.Regex.Applicative

data Protocol = HTTP | FTP deriving Show

protocol :: RE Char Protocol
protocol = HTTP <$ string "http" <|> FTP <$ string "ftp"

type Host = String
type Location = String
data URL = URL Protocol Host Location deriving Show

host :: RE Char Host
host = many $ psym $ (/= '/')

url :: RE Char URL
url = URL <$> protocol <* string "://" <*> host <* sym '/' <*> many anySym

main = print $ "http://stackoverflow.com/questions" =~ url

Ответ 4

regexpr - это еще один PCRE-ish lib, который кросс-платформенный и быстрый для начала.

Ответ 5

Я нахожу rex, что тоже очень приятно, его интеграция с ViewPatterns - хорошая идея, я думаю.

Он может быть многословным, но частично связанным с понятием регулярного выражения.

parseDate :: String -> LocalTime
parseDate [rex|(?{read -> year}\d+)-(?{read -> month}\d+)-
        (?{read -> day}\d+)\s(?{read -> hour}\d+):(?{read -> mins}\d+):
        (?{read -> sec}\d+)|] =
    LocalTime (fromGregorian year month day) (TimeOfDay hour mins sec)
parseDate [email protected]_ = error $ "invalid date " ++ v

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