Unescaping символы в строке с Ruby
Имеется строка в следующем формате (API Posterous возвращает сообщения в этом формате):
s="\\u003Cp\\u003E"
Как я могу преобразовать его в фактические символы ASCII так, чтобы s="<p>"
?
На OSX я успешно использовал Iconv.iconv('ascii', 'java', s)
но после развертывания в Heroku я получаю Iconv::IllegalSequence
исключение. Я предполагаю, что система, которую развертывает Heroku, не поддерживает java
кодировщик.
Я использую HTTParty, чтобы сделать запрос к Posterous API. Если я использую curl, чтобы сделать тот же запрос, то я не получаю двойную косую черту.
Со страницы HTTParty github:
Автоматический анализ JSON и XML в рубиновые хэши на основе типа содержимого ответа
API Posterous возвращает JSON (без двойной косой черты), а JSON-анализ HTTParty вставляет двойную косую черту.
Вот простой пример того, как я использую HTTParty для выполнения запроса.
class Posterous
include HTTParty
base_uri "http://www.posterous.com/api/2"
basic_auth "username", "password"
format :json
def get_posts
response = Posterous.get("/users/me/sites/9876/posts&api_token=1234")
# snip, see below...
end
end
С очевидной информацией (имя пользователя, пароль, site_id, api_token) заменены на допустимые значения.
В момент обрезки, response.body
содержит строку Ruby в формате JSON и response.parsed_response
содержит хеш-объект Ruby, который HTTParty создал путем анализа ответа JSON от Posterous API.
В обоих случаях последовательности Unicode, такие как \u003C
были изменены на \\u003C
,
4 ответа
Я столкнулся с этой проблемой на днях. В синтаксическом анализаторе json есть ошибка, которую использует HTTParty (Crack gem) - в основном он использует регистрозависимое регулярное выражение для последовательностей Unicode, поэтому, поскольку Posterous выпускает AF вместо af, Crack не удаляет их. Я отправил запрос на удаление, чтобы это исправить.
В то же время HTTParty приятно позволяет вам указать альтернативные парсеры, так что вы можете сделать ::JSON.parse
Обход Crack полностью так:
class JsonParser < HTTParty::Parser
def json
::JSON.parse(body)
end
end
class Posterous
include HTTParty
parser ::JsonParser
#....
end
Я нашел решение этой проблемы. Я столкнулся с этой сущностью. У elskwid была такая же проблема, и она пропустила строку через JSON-анализатор:
s = ::JSON.parse("\\u003Cp\\u003E")
Сейчас, s = "<p>"
,
Вы также можете использовать pack
:
"a\\u00e4\\u3042".gsub(/\\u(....)/){[$1.hex].pack("U")} # "aäあ"
Или сделать наоборот:
"aäあ".gsub(/[^ -~\n]/){"\\u%04x"%$&.ord} # "a\\u00e4\\u3042"
Двойная обратная косая черта выглядит почти как обычная строка, просматриваемая в отладчике.
Строка "\u003Cp\u003E"
на самом деле "<p>"
, только \u003C
Юникод для <
а также \003E
является >
,
>> "\u003Cp\u003E" #=> "<p>"
Если вы действительно получаете строку с двойной обратной косой чертой, то вы можете попробовать снять одну из пары.
В качестве теста посмотрите, какова длина строки:
>> "\\u003Cp\\u003E".size #=> 13
>> "\u003Cp\u003E".size #=> 3
>> "<p>".size #=> 3
Все вышеперечисленное было сделано с использованием Ruby 1.9.2, который поддерживает Unicode. v1.8.7 не было. Вот что я получаю, используя для сравнения 1.8.7 IRB:
>> "\u003Cp\u003E" #=> "u003Cpu003E"