3

"Divinités" (9 文字) が "Divinit\303\251s" (16 文字の長さの実際のテキスト データ) として表される入力がありますが、それを Haskell の適切にエンコードされたText(またはByteString、またはString) に変換するにはどうすればよいですか?

4

1 に答える 1

2

最初に、各エスケープ シーケンスを 1 つに変換する文字列をエスケープ解除する必要がありますChar。次に、utf8-stringpackage を使用して、結果を実際の utf8 文字列にデコードします。

import Data.Char
import Codec.Binary.UTF8.String (decodeString)

input :: String
input = "Divinit\\303\\251s"

main = maybe (return ()) putStrLn $ convertString input

convertString :: [Char] -> Maybe [Char]
convertString = fmap decodeString . unescape

unescape :: [Char] -> Maybe [Char]
unescape [] = Just []
unescape ('\\' : tail) = do
  headResult <- fmap toEnum . octalDigitsToInt . take 3 $ tail
  tailResult <- unescape . drop 3 $ tail
  return $ headResult : tailResult
unescape (head : tail) = fmap (head :) . unescape $ tail

octalDigitsToInt :: [Char] -> Maybe Int
octalDigitsToInt = 
  fmap sum . sequence .
    map (\(i, c) -> fmap (8^i*) $ octalDigitToInt c) .
      zip [0..] . reverse

octalDigitToInt :: Char -> Maybe Int
octalDigitToInt c | isOctDigit c = Just $ digitToInt c
octalDigitToInt _ = Nothing
于 2013-02-04T11:27:02.323 に答える