
In the specific case of parsing --version strings, I'm not sure regexes are any easier. Using words and then selecting the Nth word seems to do pretty well.
for comparison, see the examples below:-) There's no reason this can't be massaged further, but it already allows for IO if necessary (I like that it is compact and self-documenting -the comments have become part of the patterns, but if you don't want to match against the precise message format, you can use more of [^[:space:]]* - pity that \S* isn't posix..). Claus import Text.Regex import System.Process(runInteractiveProcess) import System.IO(hGetContents) test = mapM_ ((print =<<) . getVersion) programs getVersion (prg,flag,io,extract) = do (i,o,e,p) <- runInteractiveProcess prg [flag] Nothing Nothing version <- hGetContents ([o,e]!!(io-1)) >>= extract return (prg,version) defaultMatch :: String -> String -> IO String defaultMatch pattern = return . maybe "" head . (matchRegex (mkRegex pattern)) programs = [ghc,ghcPkg,happy,alex,haddock] ghc = ("ghc","--numeric-version",1, defaultMatch "([^[:space:]]*)") ghcPkg = ("ghc-pkg","--version",1, defaultMatch "GHC package manager version ([^[:space:]]*)") happy = ("happy","--version",1, defaultMatch "Happy Version ([^[:space:]]*)") alex = ("alex","--version",1, defaultMatch "Alex version ([.0-9]*)") haddock = ("haddock","--version",1, defaultMatch "Haddock version ([.0-9]*)")