不区分大小写的正则表达式

时间:2009-06-17 15:37:32

标签: regex haskell case-insensitive

在Haskell

中使用带有选项(标志)的正则表达式的最佳方法是什么

我用

Text.Regex.PCRE

文档列出了一些有趣的选项,如compCaseless,compUTF8,... 但我不知道如何使用(=〜)

3 个答案:

答案 0 :(得分:17)

所有Text.Regex.*模块都大量使用类型类,它们具有可扩展性和“重载”类似的行为,但仅仅看到类型就不那么明显了。

现在,您可能已经从基本的=~匹配器开始了。

(=~) ::
  ( 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

要使用=~,LHS必须存在RegexMaker ...的实例,RHS和结果必须存在RegexContext ...

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=RegexcompOpt=CompOptionexecOpt=ExecOptionsource=String)表示可以编译regex来自某种形式compOpt,execOpt的{​​{1}}个选项。 (另外,给定一些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=Regexsource=String)表示可以匹配target=Boolsource产生regex。 (给定这些特定targettarget的其他有效regexsourceIntMatchResult String等。

将这些放在一起很明显,MatchArray=~只是便利功能

=~~

并且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等。

答案 1 :(得分:9)

我对Haskell一无所知,但如果您使用的是基于PCRE的正则表达式库,那么您可以在正则表达式中使用模式修饰符。要以不区分大小写的方式匹配“无壳”,可以在PCRE中使用此正则表达式:

(?i)caseless

模式修饰符(?i)会覆盖在正则表达式之外设置的任何区分大小写或不区分大小写的选项。它也适用于不允许您设置任何选项的操作员。

类似地,(?s)打开“单线模式”,使点匹配线断开,(?m)打开“多线模式”,这使得^和$匹配换行符,和(?x)打开自由间距模式(非字符空格和字符类外的换行符是无关紧要的)。你可以组合字母。 (?ismx)打开一切。连字符会关闭选项。 (?-i)使正则表达式区分大小写。 (?x-i)启动一个自由间隔区分大小写的正则表达式。

答案 2 :(得分:8)

如果您希望使用compOpt以外的defaultCompOpt,我认为不能使用(=〜)。

像这样的工作:

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

以下两篇文章可以为您提供帮助:

Real World Haskell, Chapter 8. Efficient file processing, regular expressions, and file name matching

A Haskell regular expression tutorial