区分Haskell中的空regexp匹配项和无匹配项
我正在尝试使用区分Haskell中的空regexp匹配项和无匹配项,regex,haskell,pcre,Regex,Haskell,Pcre,我正在尝试使用regex pcre,但是regex base包含了太多的RegexContext重载,因此我不知道手头的任务应该使用哪个重载 我希望通过以下方式将字符串与(foo)-(bar)|(qux)-(qux)(q*u*u*x*)正则表达式匹配: myMatch :: String -> Maybe (String, String, Maybe String) 样本输出: myMatch“dfjdjk”应该是Nothing,因为没有匹配项 myMatch“foo-bar”应该是J
regex pcre
,但是regex base
包含了太多的RegexContext
重载,因此我不知道手头的任务应该使用哪个重载
我希望通过以下方式将字符串与(foo)-(bar)|(qux)-(qux)(q*u*u*x*)
正则表达式匹配:
myMatch :: String -> Maybe (String, String, Maybe String)
样本输出:
应该是myMatch“dfjdjk”
,因为没有匹配项Nothing
应该是myMatch“foo-bar”
,因为在第一个备选方案中没有第三个捕获组Just(“foo”,“bar”,Nothing)
应该是myMatch“quux quuxqu”
Just(“quux”,“quux”,Just“qu”)
应该是myMatch“qux-qux”
,因为第三个捕获组存在但为空Just(“qux”,“qux”,Just”)
这不是一个任务,我只是困惑于在没有匹配或没有捕获组的情况下如何不包含代码路径实现它的一种方法是使用
getAllTextSubmatches
:
import Text.Regex.PCRE
myMatch :: String -> Maybe (String, String, Maybe String)
myMatch str = case getAllTextSubmatches $ str =~ "(foo)-(bar)|(quux)-(quux)(q*u*u*x*)" :: [String] of
[] -> Nothing
[_, g1, g2, "", "", ""] -> Just (g1, g2, Nothing)
[_, "", "", g3, g4, g5] -> Just (g3, g4, Just g5)
当getAllTextSubmatches
将[String]
作为返回类型时,如果没有匹配项,它将返回一个空列表,或者返回一个包含第一个匹配项的所有捕获组(其中索引0是整个匹配项)的列表
或者,如果匹配的组可能为空,并且无法对空字符串进行模式匹配,则可以使用[(string,(MatchOffset,MatchLength))]
作为getAllTextSubmatches
的返回类型,并使用-1进行模式匹配MatchOffset
来标识不匹配的组:
myMatch :: String -> Maybe (String, String, Maybe String)
myMatch str = case getAllTextSubmatches $ str =~ "(foo)-(bar)|(quux)-(quux)(q*u*u*x*)" :: [(String, (MatchOffset, MatchLength))] of
[] -> Nothing
[_, (g1, _), (g2, _), (_, (-1, _)), (_, (-1, _)), (_, (-1, _))] -> Just (g1, g2, Nothing)
[_, (_, (-1, _)), (_, (-1, _)), (g3, _), (g4, _), (g5, _)] -> Just (g3, g4, Just g5)
现在,如果这看起来太冗长:
{-# LANGUAGE PatternSynonyms #-}
pattern NoMatch = ("", (-1, 0))
myMatch :: String -> Maybe (String, String, Maybe String)
myMatch str = case getAllTextSubmatches $ str =~ "(foo)-(bar)|(quux)-(quux)(q*u*u*x*)" :: [(String, (MatchOffset, MatchLength))] of
[] -> Nothing
[_, (g1, _), (g2, _), NoMatch, NoMatch, NoMatch] -> Just (g1, g2, Nothing)
[_, NoMatch, NoMatch, (g3, _), (g4, _), (g5, _)] -> Just (g3, g4, Just g5)
要区分何时没有匹配,请使用,以便将结果放入
Maybe
单子中。如果没有匹配项,它将使用fail
返回Nothing
myMatch :: String -> Maybe (String, String, Maybe String)
myMatch str = do
let regex = "(foo)-(bar)|(quux)-(quux)(q*u*u*x*)"
groups <- getAllTextSubmatches <$> str =~~ regex :: Maybe [String]
case groups of
[_, g1, g2, "", "", ""] -> Just (g1, g2, Nothing)
[_, "", "", g3, g4, g5] -> Just (g3, g4, Just g5)
myMatch::String->Maybe(String,String,Maybe String)
myMatch str=do
let regex=“(foo)-(bar)|(qux)-(qux)(q*u*u*x*)”
组(g1、g2、无)
只是(g3,g4,g5)
使用regex applicative
myMatch = match re
re = foobar <|> quuces where
foobar = (,,) <$> "foo" <* "-" <*> "bar" <*> pure Nothing
quuces = (,,)
<$> "quux" <* "-"
<*> "quux"
<*> (fmap (Just . mconcat) . sequenceA)
[many $ sym 'q', many $ sym 'u', many $ sym 'u', many $ sym 'x']
myMatch=match-re
re=foobar quuces在哪里
foobar=(,,“foo”你需要锚定:这取决于我想要什么:)我想要“fdoifoo bardjfkj”
也被匹配:)我可能不明白,但你的表达式是按照你描述的方式工作的:用以将目标
包装在单子中,比如可能
@4castle,你能把你的评论作为答案吗?在foobarfoobar
上会失败吗?我只需要比赛一次。模式匹配在mrSubList x=~~(foo)-(bar)|(qux)-(qux)(q*u*u*x*)“
上更好吗?@nponeccop应该只给出第一个匹配。我还没有实际测试我的代码,所以我可能需要编辑它,但希望这能证明我的想法。不幸的是,这不起作用:列表总是6个元素长,不匹配的捕获都是“
。下面是一个简短的说明:(*)foo |(*)bar
。在Perl中,$1
和$2
是'
或未定义的
,因此可以将不匹配的捕获组与匹配但为空的捕获组区分开来。@nponeccop我的系统现在正在使用它。我使用的是regex-pcre-builtin
。我希望它能够更好地区分不匹配的捕获组,但在这种情况下,“
将起作用。然后我可以编写一个包装器,用无
向不匹配的组发送信号。干得好
re = foobar <|> quuces where
foobar = do
foo <- "foo"
_ <- "-"
bar <- "bar"
pure (foo, bar, Nothing)
quuces = do
quux1 <- "quux"
_ <- "-"
quux2 <- "quux"
quux3 <- fmap snd . withMatched $
traverse (many . sym) ("quux" :: [Char])
-- [many $ sym 'q', many $ sym 'u', many $ sym 'u', many $ sym 'x']
pure (quux1, quux2, Just quux3)