人気ブログランキング | 話題のタグを見る

Parsec セパレータ

"abc, def, ghi" のようなCSVのデータのようにデータがセパレータで分けられているものがある。こういう文字列を効果的に処理できるのが、sepBy コンビネータだ。sepBy コンビネータは、第1引数にデータ部分のパーサを、第2引数にセパレータのパーサをとる。戻り値はデータのリストだ(Parser モナドの形で返される)。many, many1 の時と同じく、データが0個でもマッチする sebBy と、最低1個のデータが必要な sepBy1 がある。

Hugs> :l Text.ParserCombinators.Parsec
Text.ParserCombinators.Parsec> parseTest (sepBy word (char ',')) "abc,def,ghi" where word = many1 letter
["abc","def","ghi"]

Parsec, a fast combinator parser には、sepBy1 に加えて、セパレータ前後の空白を無視する機能、複数個の行末の区切り文字を認識してパースを中止する機能を加えた例 sentence が紹介されている。

import Text.ParserCombinators.Parsec

sentence    :: Parser [String]
sentence    = do{ words <- sepBy1 word separator
                ; oneOf ".?!"
                ; return words
                }
                
separator   :: Parser ()
separator   = skipMany1 (space <|> char ',')

word :: Parser String
word = many1 letter

実行例:
Main> parseTest sentence "hi,di,hi."
["hi","di","hi"]
by tnomura9 | 2009-09-30 11:38 | Haskell | Comments(0)
<< Parsec ユーザ定義のエラ... Parsec 文字や文字列の繰り返し >>