регулярные выражения без учета регистра

каков наилучший способ использования регулярных выражений с параметрами (флагами) в Haskell

Я использую

Text.Regex.PCRE

в документации перечислены несколько интересных опций, таких как compCaseless, compUTF8, ... Но я не знаю, как использовать их с (=~)

3 ответов


все Text.Regex.* модули интенсивно используют typeclasses, которые существуют для расширяемости и"перегрузки", но делают использование менее очевидным из-за того, что просто видят типы.

теперь, вы, вероятно, были начаты с основного =~ matcher.

(=~) ::
  ( RegexMaker Regex CompOption ExecOption source
  , RegexContext Regex source1 target )
  => source1 -> source -> target
(=~~) ::
  ( RegexMaker Regex CompOption ExecOption source
  , RegexContext Regex source1 target, Monad m )
  => source1 -> source -> m target

использовать =~, должен существовать экземпляр RegexMaker ... для LHS, и RegexContext ... для RHS и результата.

class RegexOptions regex compOpt execOpt | ...
      | regex -> compOpt execOpt
      , compOpt -> regex execOpt
      , execOpt -> regex compOpt
class RegexOptions regex compOpt execOpt
      => RegexMaker regex compOpt execOpt source
         | regex -> compOpt execOpt
         , compOpt -> regex execOpt
         , execOpt -> regex compOpt
  where
    makeRegex :: source -> regex
    makeRegexOpts :: compOpt -> execOpt -> source -> regex

действующий экземпляр всех этих классов (например, regex=Regex, compOpt=CompOption, execOpt=ExecOption и source=String) означает, что можно скомпилировать regex С compOpt,execOpt параметры из некоторой формы source. (Также, учитывая некоторые regex тип, есть ровно один compOpt,execOpt установить, что идет вместе с ним. Много разных source типы в порядке, хотя.)

class Extract source
class Extract source
      => RegexLike regex source
class RegexLike regex source
      => RegexContext regex source target
  where
    match :: regex -> source -> target
    matchM :: Monad m => regex -> source -> m target

действующий экземпляр всех этих классов (например, regex=Regex, source=String, target=Bool) означает, что можно сопоставить source и regex выход target. (Другое действительное targets учитывая эти конкретные regex и source are Int, MatchResult String, MatchArray, etc.)

поставить их вместе, и это довольно очевидно, что =~ и =~~ просто удобство функции

source1 =~ source
  = match (makeRegex source) source1
source1 =~~ source
  = matchM (makeRegex source) source1

а также =~ и =~~ не оставляйте места для передачи различных вариантов makeRegexOpts.

вы могли бы сделать свой собственный

(=~+) ::
   ( RegexMaker regex compOpt execOpt source
   , RegexContext regex source1 target )
   => source1 -> (source, compOpt, execOpt) -> target
source1 =~+ (source, compOpt, execOpt)
  = match (makeRegexOpts compOpt execOpt source) source1
(=~~+) ::
   ( RegexMaker regex compOpt execOpt source
   , RegexContext regex source1 target, Monad m )
   => source1 -> (source, compOpt, execOpt) -> m target
source1 =~~+ (source, compOpt, execOpt)
  = matchM (makeRegexOpts compOpt execOpt source) source1

который можно использовать как

"string" =~+ ("regex", CompCaseless + compUTF8, execBlank) :: Bool

или перезаписать =~ и =~~ С методами, которые могут принимать параметры

import Text.Regex.PCRE hiding ((=~), (=~~))

class RegexSourceLike regex source
  where
    makeRegexWith source :: source -> regex
instance RegexMaker regex compOpt execOpt source
         => RegexSourceLike regex source
  where
    makeRegexWith = makeRegex
instance RegexMaker regex compOpt execOpt source
         => RegexSourceLike regex (source, compOpt, execOpt)
  where
    makeRegexWith (source, compOpt, execOpt)
      = makeRegexOpts compOpt execOpt source

source1 =~ source
  = match (makeRegexWith source) source1
source1 =~~ source
  = matchM (makeRegexWith source) source1

или вы можете просто использовать match, makeRegexOpts, etc. непосредственно там, где это необходимо.


Я считаю, что не могу использовать ( = ~ ), если вы хотите использовать compOpt кроме defaultCompOpt.

что-то вроде этой работы:

match (makeRegexOpts compCaseless defaultExecOpt  "(Foo)" :: Regex) "foo" :: Bool

следующие две статьи должны помочь вам:

Реальный Мир Хаскелл, Глава 8. Эффективная обработка файлов, регулярные выражения и сопоставление имен файлов

учебник по регулярному выражению Haskell


Я ничего не знаю о Haskell, но если вы используете библиотеку регулярных выражений на основе PCRE, то вы можете использовать модификаторы режима внутри регулярного выражения. Чтобы соответствовать "caseless" в нечувствительном случае, вы можете использовать это регулярное выражение в PCRE:

(?i)caseless

режим модификатор (?i) переопределяет любой параметр чувствительности к регистру или нечувствительности к регистру, установленный вне регулярного выражения. Он также работает с операторами, которые не позволяют установить любые параметры.

аналогично, (?s) включает "однострочный режим", который делает разрывы линии совпадения точек, (?m) включает "многострочный режим", который делает ^ и $ совпадающими при разрывах строк, и (?x) включает режим свободного интервала (пробелы и разрывы строк вне классов символов незначительны). Вы можете комбинировать буквы. (?ismx) включает все. Дефис отключает опции. (?- i) делает регистр regex чувствительным. (?x-i) запускает чувствительное к регистру регулярное выражение со свободным интервалом.