заменить двойную обратную косую черту одинарной обратной косой чертой в haskell

Я хочу заменить «\\» из последовательности байтов (Data.ByteString) на «\», но из-за внутреннего экранирования «\» это не сработает. Рассмотрим следующий пример:

Исходная строка байтов:

"\159\DEL*\150\222/\129vr\205\241=mA\192\184"

После сохранения и повторного чтения из базы данных я получаю следующую строку байтов:

 "\"\\159\\DEL*\\150\\222/\\129vr\\205\\241=mA\\192\\184\""

Представьте, что строка байтов используется в качестве криптографического ключа, который теперь является неправильным ключом из-за недопустимых символов в последовательности. Эта проблема на самом деле возникает из-за неправильного представления базы данных (varchar вместо bytea), потому что в противном случае это считается недопустимой последовательностью utf-8. Я попытался заменить недопустимые символы, используя какой-то подход split-modify-concat, но все, что я получаю, это что-то без обратной косой черты внутри последовательности, потому что я не могу вставить одну обратную косую черту в строку байтов.

Очень прошу вашей помощи.


person auermich    schedule 11.06.2016    source источник
comment
Вы хотите заменить персонажа на себя? Я не могу понять. В любом случае, дважды проверьте, не используете ли вы случайно некоторые экранирующие функции, такие как show, которые добавляют нежелательные escape-последовательности.   -  person chi    schedule 11.06.2016
comment
Как вы храните строку в базе данных? Я думаю, в этом твоя проблема.   -  person ErikR    schedule 11.06.2016
comment
@ErikR Верно, но я думаю, что часть цели этого вопроса состоит в том, чтобы исправить повреждение строк, уже сохраненных в базе данных.   -  person chepner    schedule 11.06.2016
comment
Пожалуйста, отредактируйте свой вопрос. StackOverflow использует markdown, а не открытый текст, поэтому ваши строки, содержащие обратную косую черту, не отображаются должным образом.   -  person leftaroundabout    schedule 11.06.2016
comment
разделите начальные и конечные кавычки и приведите их к bytea   -  person Jasen    schedule 11.06.2016
comment
Форматирование все равно неправильное.   -  person leftaroundabout    schedule 11.06.2016
comment
Я отредактировал вопрос @leftaroundabout. Я не могу сохранить его как bytea из-за неправильной кодировки. Более того, кажется, что сохранение его как SqlString и его извлечение, которое возвращается как SqlByteString, позволяет достичь наилучшего результата, а именно упомянутого выше.   -  person auermich    schedule 11.06.2016
comment
@chi, я использую show, чтобы получить строку из строки байтов. Я также пытался использовать функцию распаковки, но без другого результата.   -  person auermich    schedule 11.06.2016
comment
show предназначено для экранирования забавных символов, распаковка должна сохранить строку как есть   -  person chi    schedule 11.06.2016
comment
На самом деле данные правильно хранятся в базе данных, но чтение из базы данных не работает должным образом. Должна быть какая-то ошибка в функции преобразования fromSql. Еще хуже, когда вам нужно обрабатывать как ленивые, так и строгие строки байтов, поскольку поддерживаются только строгие строки байтов.   -  person auermich    schedule 11.06.2016


Ответы (2)


Возможно, вам подойдет read:

import Data.ByteString.Char8 as BS

bad =  BS.pack "\"\\159\\DEL*\\150\\222/\\129vr\\205\\241=mA\\192\\184\""

good = read (BS.unpack bad) :: BS.ByteString

-- returns: "\159\DEL*\150\222/\129vr\205\241=mA\192\184"

Вы также можете использовать readMaybe вместо этого для более безопасного синтаксического анализа.

person ErikR    schedule 11.06.2016

возможно, вам нужно выражение postgresql

substring(ByteString from e'^\\"(.*)\\"$')::bytea

это даст результат bytea, который можно использовать в запросах или в alter table-using DDL.

person Jasen    schedule 11.06.2016