我正在处理从遗留数据库导入到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/

10-11 08:15