在Haskell
中使用带有选项(标志)的正则表达式的最佳方法是什么我用
Text.Regex.PCRE
文档列出了一些有趣的选项,如compCaseless,compUTF8,... 但我不知道如何使用(=〜)
答案 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=Regex
,compOpt=CompOption
,execOpt=ExecOption
和source=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=Regex
,source=String
)表示可以匹配target=Bool
和source
产生regex
。 (给定这些特定target
和target
的其他有效regex
为source
,Int
,MatchResult 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
以下两篇文章可以为您提供帮助: