操作系统:MacOSX 10.7.1 来自brew的GHC和Haskell平台。
GHCi, version 7.0.4: http://www.haskell.org/ghc/ :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
Loading package ffi-1.0 ... linking ... done.
Prelude> :m +Text.Regex.Posix
Prelude Text.Regex.Posix> "foo" =~ "o" :: [String]
<interactive>:1:7:
No instance for (RegexContext Regex [Char] [String])
arising from a use of `=~'
Possible fix:
add an instance declaration for
(RegexContext Regex [Char] [String])
In the expression: "foo" =~ "o" :: [String]
In an equation for `it': it = "foo" =~ "o" :: [String]
Prelude Text.Regex.Posix> "foo" =~ "o" :: String
Loading package array-0.3.0.2 ... linking ... done.
Loading package bytestring-0.9.1.10 ... linking ... done.
Loading package containers-0.4.0.0 ... linking ... done.
Loading package transformers-0.2.2.0 ... linking ... done.
Loading package mtl-2.0.1.0 ... linking ... done.
Loading package regex-base-0.93.2 ... linking ... done.
Loading package regex-posix-0.95.1 ... linking ... done.
"o"
我相信库已更新。我认为"foo" =~ "o" :: [String]
的输出是["o", "o"]
任何建议都会受到赞赏。
答案 0 :(得分:11)
ghci> getAllTextMatches ("foo" =~ "o" :: AllTextMatches [] String)
["o", "o"]
我没有在Haskell中使用正则表达式(我认为Dan Burton's answer更加惯用)。
所以我想出来的方式是我查看了你的类型错误No instance for (RegexContext Regex [Char] [String])
,并弹出了ghci:
ghci> :t (=~)
(=~)
:: (RegexMaker Regex CompOption ExecOption source,
RegexContext Regex source1 target) =>
source1 -> source -> target
所以RegexContext Regex [Char] [String]
是一个包含返回类型"foo" =~ "o" :: [String]
的类。所以我看看这个类的实例确实存在,所以我可以找出允许返回值的内容:
ghci> :i RegexContext
class RegexLike
regex source => RegexContext regex source target where
match :: regex -> source -> target
matchM :: Monad m => regex -> source -> m target
-- Defined in Text.Regex.Base.RegexLike
instance RegexContext Regex String String
-- Defined in Text.Regex.Posix.String
instance RegexLike a b => RegexContext a b [[b]]
-- Defined in Text.Regex.Base.Context
...
instance RegexLike a b => RegexContext a b (AllTextMatches [] b)
-- Defined in Text.Regex.Base.Context
...
AllTextMatches
名称似乎表明您在寻找什么,所以我检查了一下:
ghci> :i AllTextMatches
newtype AllTextMatches f b
= AllTextMatches {getAllTextMatches :: f b}
-- Defined in Text.Regex.Base.RegexLike
instance RegexLike a b => RegexContext a b (AllTextMatches [] b)
-- Defined in Text.Regex.Base.Context
所以这是用于提取所有文本匹配的类型,正如我怀疑的那样。我需要做的就是表明我想要一个这种类型的返回值。
还注意[[b]]
的可能返回类型,我假设它返回包含每个完整匹配及其所有子匹配的列表列表:
ghci> "foo" =~ "o" :: [[String]]
[["o"],["o"]]
ghci> "foo bar baz" =~ "[aeiou](.)" :: [[String]]
[["oo","o"],["ar","r"],["az","z"]]
所以也许这是你打算使用的类型,而不是[String]
。当[String]
存在时,我可以看到[[String]]
略微含糊不清 - "foo bar baz" =~ "[aeiou](.)" :: [String]
应fst ("foo bar baz" =~ "[aeiou](.)" :: [[String]])
或map fst ("foo bar baz" =~ "[aeiou](.)" :: [[String]])
。
答案 1 :(得分:9)
这也有效
ghci> getAllTextMatches $ "foo" =~ "o" :: [String]
["o","o"]
答案 2 :(得分:3)
试试这个:
Prelude Text.Regex.Posix> getAllTextMatches ("foo" =~ "o" :: AllTextMatches [] String)
["o","o"]
答案 3 :(得分:2)
另一种可能的解决方案是:
map head $ "foo" =~ "o" :: [String]
将(=~)
的结果绑定到[[String]]
将产生匹配列表,其中每个匹配由字符串列表表示。在每个列表中,其head
将是整个匹配,并且tail
匹配每个子匹配:
> "foo goo bar" =~ "(.)o(.)" :: [[String]]
[["foo","f","o"],["goo","g","o"]]
-- Get the second submatch (2) of the first match (0)
> "foo goo bar" =~ "(.)o(.)" !! 0 !! 2 :: String
"o"
-- Get the first submatch (1) of the second match (1)
> "foo goo bar" =~ "(.)o(.)" !! 1 !! 1 :: String
"g"
简而言之,map head $ string =~ regexp :: [String]
包含regexp
中string
的完整匹配。 map tail $ string =~ regexp :: [[String]]
包含子匹配,在原始正则表达式中通过括起括号()
来表示。