Неэкранирующие символы в строке с помощью Ruby
Вопрос
Задана строка в следующем формате (Posterous API возвращает сообщения в этом формате):
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 в хэши ruby на основе ответа тип содержимого
Posterous API возвращает 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.
В обоих случаях используются последовательности Юникода, такие как \u003C
были изменены на \\u003C
.
Решение
На днях я столкнулся именно с этой проблемой.В анализаторе json, который использует HTTParty, есть ошибка (Crack gem) - в основном он использует чувствительное к регистру регулярное выражение для последовательностей Unicode, поэтому, поскольку Posterous выдает A-F вместо a-f , 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
является ли unicode для <
и \003E
является >
.
>> "\u003Cp\u003E" #=> "<p>"
Если вы действительно получаете строку с удвоенной обратной косой чертой, то вы могли бы попробовать удалить одну из пары.
В качестве теста посмотрите, какой длины строка:
>> "\\u003Cp\\u003E".size #=> 13
>> "\u003Cp\u003E".size #=> 3
>> "<p>".size #=> 3
Все вышесказанное было сделано с использованием Ruby 1.9.2, который поддерживает Unicode.версии v1.8.7 не было.Вот что я получаю, используя IRB 1.8.7 для сравнения:
>> "\u003Cp\u003E" #=> "u003Cpu003E"