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

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

Documentation
Coming soonish.

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

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

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

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

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


person Nick Brunt    schedule 24.10.2011    source источник


Ответы (5)


Что ж, я написал большую часть вики-страницы и, возможно, написал «Скоро будет». Пакет regex-pcre был моей оболочкой PCRE с использованием интерфейса regex-base, где regex-base используется в качестве интерфейса для нескольких очень разных серверных модулей механизма регулярных выражений. В пакете pcre-light Дона Стюарта нет этого уровня абстракции, поэтому он намного меньше.

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

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

person Chris Kuklewicz    schedule 25.10.2011

Я также написал написанное мной 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
person Roman Cheplyaka    schedule 26.10.2011

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

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

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

Итак, предполагая, что вы используете regex-pcre:

  • Согласно этому ответу, да.

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

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

person ivanm    schedule 24.10.2011
comment
Я получаю сообщение об ошибке Not in scope 'compNewLine', когда пробую этот метод для многострочного сопоставления. Я думаю, это работает только для Posix. - person Nick Brunt; 25.10.2011
comment
@NickBrunt compMultiline, может быть, тогда? - person ivanm; 25.10.2011
comment
Разве pcre-light-extras не противоречит? - person mcandre; 25.10.2011
comment
@mcandre: да, я полагаю, два последних слова компенсируют друг друга ...: p - person ivanm; 25.10.2011

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

person Simon Michael    schedule 24.10.2011

Я считаю, что 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 v@_ = error $ "invalid date " ++ v

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

person Emmanuel Touzery    schedule 14.02.2014