{-# OPTIONS_HADDOCK hide #-} -- | Match Glob patterns by convertng them to Regular Expressions. -- Code is take from the book of "Real World Haskell". module Language.Hanspell.Glob (matchGlob, matchGlobs) where import Text.Regex import Data.Maybe -- | Checks if a string matches a glob pattern by converting that glob -- pattern to a regular expression and matching using that. matchGlob :: String -> String -> Bool matchGlob glob string = isJust (matchRegex (mkRegex (globToRegex glob)) string) -- | Checks if a string matches any of glob patterns. matchGlobs :: [String] -> String -> Bool matchGlobs globs string = any (`matchGlob` string) globs -- Converts a Glob Expression into a Regular Expression, anchor it to the -- beginning and end of the line globToRegex :: String -> String globToRegex globex = '^' : globToRegex' globex ++ "$" -- Finds glob specific characters, and convert them to regex specific -- characters, escapes regex specific characters and verify that character -- classes are properly terminated globToRegex' :: String -> String globToRegex' "" = "" globToRegex' ('*':cs) = ".*" ++ globToRegex' cs globToRegex' ('?':cs) = '.' : globToRegex' cs globToRegex' ('[':'!':c:cs) = "[^" ++ c : charClass cs globToRegex' ('[':c:cs) = '[' : c : charClass cs globToRegex' ('[':_) = error "unterminated character class" globToRegex' (c:cs) = escape c ++ globToRegex' cs -- Escapes regex characters. escape :: Char -> String escape c | c `elem` regexChars = '\\' : [c] | otherwise = [c] where regexChars = "\\+()^$.{}]" -- Verifies character classes are terminated. charClass :: String -> String charClass (']':cs) = ']' : globToRegex' cs charClass (c:cs) = c : charClass cs charClass [] = error "unterminated character class"