Здравствуйте, Tonal-, Вы писали:
T>Есть файлы в кодировке windows-1251.
T>Нужно выдернуть из них несколько значений с помощью регулярок (Text.Regex.PCRE).
T>Как наиболее просто это сделать?
T>Попробывал записать выражение как есть — получил ошибку синтаксиса.
T>Перевёл исходник в UTF-8 всё вроде бы компилиться, но выражения, в которых присутствуют русские символы не находит.
T>Куда копать?
T>Винда ghc 6.10.1
1. исходники в ghc записываются в utf-8
2. строки хранятся в unicode кодировке (4 байта на символ)
3. файлы читаются байт-в-байт. поэтому значение 140, к примеру, превратится в unicode символ с кодом 140. твоя задача — превратить 140 в число, соответствующее нужной русской букве
для этого в винде (если у тебя русская локаль) нужно сделать следующее:
AnsiToOemA
OemToAnsiW
и затем прочитать результат последней операции как UTF-16 кодировку. плюс к этому восстановить символы cr/lf, которые последняя операция портит
-- |Translate string from ANSI encoding to Unicode
ansi2unicode s =
if all isAscii s
then s
else iHateWindows $
unsafePerformIO $ do
withCStringLen s $ \(cstr,len) -> do
allocaBytes (len*2) $ \wstr -> do
c_AnsiToOemBuff cstr cstr (i len)
c_OemToWideBuff cstr wstr (i len)
peekCWStringLen (wstr,len)
-- |Преобразовать виндовые коды символов \r и \n в человеческий вид
iHateWindows = replace (chr 9834) '\r' . replace (chr 9689) '\n'
-- |Заменить в списке все вхождения элемента 'from' на 'to'
replace from to = map (\x -> if x==from then to else x)
foreign import stdcall unsafe "winuser.h CharToOemBuffW"
c_WideToOemBuff :: CWString -> CString -> DWORD -> IO Bool
foreign import stdcall unsafe "winuser.h OemToCharBuffW"
c_OemToWideBuff :: CString -> CWString -> DWORD -> IO Bool
foreign import stdcall unsafe "winuser.h OemToCharBuffA"
c_OemToAnsiBuff :: CString -> CString -> DWORD -> IO Bool
foreign import stdcall unsafe "winuser.h CharToOemBuffA"
c_AnsiToOemBuff :: CString -> CString -> DWORD -> IO Bool
взято из исходников freearc