hpaste

recent | annotate | new

import Text.Printf (printf)

match :: String -> String -> Bool
match ('^':xs) y = matchhere xs y
match x        y = matchhere x y

matchhere :: String -> String -> Bool
matchhere (x:'*':xs) y      = matchstar x xs y
matchhere ('$':xs)   y      = y == []
matchhere ('.':xs)   (y:ys) = matchhere xs ys
matchhere (x:xs)     (y:ys) = x == y && matchhere xs ys
matchhere []         _      = True
matchhere _          []     = False

matchstar :: Char -> String -> String -> Bool
matchstar c [] (y:ys) = c `elem` [y,'.']
matchstar c x  (y:ys) | c `elem` [y,'.'] = matchhere x ys || matchstar c x ys
                      | otherwise        = matchhere x (y:ys)
matchstar c _  _      = c == '.'


main = mapM_ check
    [("foo","foo", True),
    ("foo","bar", False),
    ("",  "foo", True),
    (".", "Foo", True),
    (".*","Foo", True),
    ("Foo$", "Foo", True),
    ("F.",   "Foo", True),
    ("F.",   "foo", False),
    ("F.*",  "Foo", True),
    ("^Fo", "Fow", True),
    ("^Fow$", "Fow", True),
    ("^Fo", "fFow", False),
    (".",  "", False),
    ("a*a",  "aaa", True),
    ("Fo*",  "Foo", True),
    ("Fo*d", "Foo", False),
    ("Fo*d", "Foooood", True)]


check (pat,str,res) = if match pat str == res 
                     then putStr "." 
                     else error $ printf "Failure: '%s' =~ /%s/ wasn't %s." str pat (b2s res)
 where b2s True  = "True"
       b2s False = "False"