我正在处理从遗留数据库导入到sqlite中进行开发的数据,遗留数据库中有许多url编码的字符串,其中包含波兰字符我可以通过使用
CGI::unescape_html( CGI::unescape "string" )
除了一个案例(我注意到了,可能还有更多因为我还没有做任何测试),字母“ó”例如,对字符串“wymiana+teflon%F3w”使用
unescapeHTML
将引发invalid byte sequence
异常。现在的问题是,我的字符串是否被正确转义,因为其他波兰字符使用的是“&nnn;”序列,如“b%26%23322%3bad+zapisu+%2d+powinno+by%26%23263%3b+brak”,这似乎遵循numeric character referencing的标准。顺便说一句,这个字符串被适当地转换成
“B_ad Zapisu-Powinno作者:奇·布拉克”
但是,另一方面,也有类似字符编码的字符串,例如“odpowietrzanie+weza%5C”,由
CGI::unescapeHTML
正确处理但是,%5C表示abackslash而不是代码点低于U+0256的字母这是原因吗我试图对此进行研究,但没有找到任何解释我还将Ruby更新为2.1.0,因为CGI::Util在新版本中发生了变化,但仍然没有成功。 最佳答案
ó
在ISO-8859-2(和ISO-8859-1)中是0xF3,但'\xF3'
不是有效的UTF-8字符串,如果您希望使用UTF-8,那么ó
应该在URL中是%C3%B3
某个地方的某个人可能使用了不推荐的escape
JavaScript function来编码字符串,而不是现代的encodeURIComponent
;您可以在浏览器的javascript控制台中通过一个简单的测试看到区别:
> escape('ó')
"%F3"
> encodeURIComponent('ó')
"%C3%B3"
你看到的是你想要看到的一件事应该是手工修复编码:
irb> CGI::unescape('wymiana+teflon%F3w').force_encoding('ISO-8859-2').encode('UTF-8')
=> "wymiana teflonów"
这假设您知道什么应该是ISO-8859-1,什么应该是UTF-8您的数据中可能混合了iso-8859-2(或-1,-3,…,windows cp-1258,…);不幸的是,由于编码重叠,没有可靠的方法来区分差异,而且如果不仔细观察并了解所涉及的各种语言,也无法确定结果的意义。
也许你能做的最好的事是:
通过
%F3
转换器发送所有信息。将它包在异常处理程序中,以捕获不可避免的问题。
把问题串藏在一边某处。
尝试将字符串从(3)转换为ISO-8859-2到UTF-8,并用眼珠打量它们,看它们是否有意义。
重复其他常见的编码,直到没有剩下你关心的东西。
请注意,我使用的是ISO-8859-2,而不是更常见的ISO-8859-1,因为拉丁语-2用于东欧语言(如波兰语),而拉丁语-1用于西欧语言它们在
%C3%B3
上重叠,但在拉丁语-1中没有像这样的任务,你通常先尝试可能存在的编码,然后再回到其他常见的编码,然后再回到你能想到的任何其他编码,然后再回到烈性酒。祝你好运,使遗留数据现代化不是世界上最有趣的工作。
关于ruby-on-rails - CGI::unescape无法处理无法逃脱的“wymiana + teflon%F3w”吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/22647125/