文字コードを変換する
UTF-8以外でエンコードされたテキストデータを扱いたい場合は,ByteStringで読み込んでからコード変換して使います.
code:_
(1) (2) (3) (4) (5) (6) (7)
Input --> ByteString --> ByteString --> Text --> Text --> ByteString --> ByteString --> Output
↓ ↑
String --> String
(1) ByteStringとして入力
(2) 文字コードをUNICODEに変換
(3) ByteStringを文字列(Text)に変換
(4) テキスト処理
(5) 文字列(Text)をByteStringに変換
(6) 文字コードをUNICODEから変換
(7) ByteStringとして出力
文字列処理で文字列をStringで表現したい場合はunpack :: Text -> Stringおよびpack :: String -> Textを使うといいでしょう.
インポート
code: (haskell)
import Data.ByteString as BS -- bytestring パッケージが提供
import Data.Text as T -- text パッケージが提供
import Data.Text.ICU.Convert -- text-icu パッケージが提供
import System.IO
テキストデータの入力
code:hs
inputWithEnc :: String -> (Handle -> IO Text)
inputWithEnc enc hdl = toUnicode <$> open enc Nothing <*> BS.hGetContents hdl
テキストデータの出力
code:hs
outputWithEnc :: String -> (Handle -> Text -> IO ())
outputWithEnc enc hdl txt = open enc Nothing >>= BS.hPutStr hdl . (fromUnicode txt)
テキストでの対話
code:hs
interactWithEnc :: String -> String -> ((Text -> Text) -> IO ())
interactWithEnc ie oe textproc = inputWithEnc ie stdin >>= outputWithEnc oe stdout . textproc
interactWithEnc' :: String -> String -> ((String -> String) -> IO ())
interactWithEnc' ie oe strproc = interactWithEnc ie oe (T.pack . strproc . T.unpack)
利用例
Shift_JISでエンコードされたテキストデータをEUC-jpでエンコードされたテキストデータに変換するプログラム
code:hs
main :: IO ()
main = interactWithEnc "Shift_JIS" "EUC-jp" id
上の例では改行を表すコードはそのまま保存されます.
改行コードを変換するなら,Data.Text.replace :: Text -> Text -> Text -> Textが使えます.
以下では改行コードを CR LF から LF に変更しています.
code:hs
main :: IO ()
main = interactWithEnc "shift_JIS" "EUC-jp" (replace "\r\n" "\n")