2013年3月5日火曜日

開発環境

Real World Haskell』(Bryan O'SullivanJohn GoerzenDon Stewart(著)、山下 伸夫伊東 勝利株式会社タイムインターメディア(翻訳)、オライリー・ジャパン、2009年、ISBN978-4-87311-423-3)の8章(効率的なファイル処理、正規表現、ファイル名マッチング)の8.5(グロブパターンを正規表現に翻訳する)の練習問題1、2.を解いてみる。

1, 2.

コード(BBEdit)

GlobRegex.hs

-- file: GlobRegex.hs
module GlobRegex
    (
      globToRegex
    , matchesGlob
    ) where

import Data.Char (toUpper)
import Text.Regex.Posix ((=~))

-- Trueの場合は大文字小文字を区別しない
-- Flaseの場合は大文字小文字を区別する
type Ignore = Bool
globToRegex :: String -> Ignore -> String
globToRegex cs i | i = '^': (map toUpper (globToRegex' cs)) ++ "$"
                 | otherwise = '^': globToRegex' cs ++ "$"

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

escape :: Char -> String
escape c | c `elem` regexChars = '\\':[c]
         | otherwise = [c]
    where regexChars = "\\+()^$.{}]|"

charClass :: String -> String
charClass (']':cs) = ']' : globToRegex' cs
charClass (c:cs) = c: charClass cs
charClass [] = error "unterminated character class"

matchesGlob :: FilePath -> String -> Ignore -> Bool
matchesGlob name pat i | i = (map toUpper name) =~ globToRegex pat i
                       | otherwise = name =~ globToRegex pat i

入出力結果(Terminal, ghci)

$ ghci
GHCi, version 7.4.2: http://www.haskell.org/ghc/  :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
Prelude> :load GlobRegex
[1 of 1] Compiling GlobRegex        ( GlobRegex.hs, interpreted )
Ok, modules loaded: GlobRegex.
*GlobRegex> matchesGlob "Taste.txt" "t[ea]s*" True
Loading package array-0.4.0.0 ... linking ... done.
Loading package bytestring-0.9.2.1 ... linking ... done.
Loading package deepseq-1.3.0.0 ... linking ... done.
Loading package containers-0.4.2.1 ... linking ... done.
Loading package transformers-0.3.0.0 ... linking ... done.
Loading package mtl-2.1.2 ... linking ... done.
Loading package regex-base-0.93.2 ... linking ... done.
Loading package regex-posix-0.95.2 ... linking ... done.
True
*GlobRegex> matchesGlob "Taste.txt" "t[ea]s*" False
False
*GlobRegex> matchesGlob "tAste.txt" "t[ea]s*" True
True
*GlobRegex> matchesGlob "tAste.txt" "t[ea]s*" False
False
*GlobRegex> globToRegex "[" False
"^*** Exception: unterminated character class
*GlobRegex> :quit
Leaving GHCi.
$

0 コメント:

コメントを投稿