修复同时包含 UTF-8 和 Windows-1252 的文件

2024-03-12

我有一个生成 UTF-8 文件的应用程序,但某些内容的编码不正确。一些字符被编码为 iso-8859-1 又名 iso-latin-1 或 cp1252 又名 Windows-1252。有没有办法恢复原文?


Yes!

显然,最好修复创建文件的程序,但这并不总是可行。以下是两种解决方案。

一行可以包含多种编码

编码::修复拉丁语 http://search.cpan.org/perldoc?Encoding::FixLatin提供了一个名为fix_latin它解码由 UTF-8、iso-8859-1、cp1252 和 US-ASCII 混合组成的文本。

$ perl -e'
   use Encoding::FixLatin qw( fix_latin );
   $bytes = "\xD0 \x92 \xD0\x92\n";
   $text = fix_latin($bytes);
   printf("U+%v04X\n", $text);
'
U+00D0.0020.2019.0020.0412.000A

虽然采用了启发式方法,但它们相当可靠。只有以下情况才会失败:

  • One of
    [ÀÁÁÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞß]
    使用 iso-8859-1 或 cp1252 编码,后跟其中之一
    [€‚▪„...†‡ˆ‰Š´ŒŽ‘’“”•–—~™š›œžŸ<NBSP>�£¤¥�§�©ª«�<SHY>® ́°±23´µ¶·¸1º»1/43¿]
    使用 iso-8859-1 或 cp1252 编码。

  • One of
    [àáâãäåæçèééêëìíîï]
    使用 iso-8859-1 或 cp1252 编码,后跟其中的两个
    [€‚▪„...†‡ˆ‰Š´ŒŽ‘’“”•–—~™š›œžŸ<NBSP>�£¤¥�§�©ª«�<SHY>® ́°±23´µ¶·¸1º»1/43¿]
    使用 iso-8859-1 或 cp1252 编码。

  • One of
    [ðñòóôõöö]
    使用 iso-8859-1 或 cp1252 编码,后跟其中的两个
    [€‚▪„...†‡ˆ‰Š´ŒŽ‘’“”•–—~™š›œžŸ<NBSP>�£¤¥�§�©ª«�<SHY>® ́°±23´µ¶·¸1º»1/43¿]
    使用 iso-8859-1 或 cp1252 编码。

使用核心模块可以产生相同的结果Encode http://search.cpan.org/perldoc?Encode,尽管我认为这比安装了 Encoding::FixLatin::XS 的 Encoding::FixLatin 要慢一些。

$ perl -e'
   use Encode qw( decode_utf8 encode_utf8 decode );
   $bytes = "\xD0 \x92 \xD0\x92\n";
   $text = decode_utf8($bytes, sub { encode_utf8(decode("cp1252", chr($_[0]))) });
   printf("U+%v04X\n", $text);
'
U+00D0.0020.2019.0020.0412.000A

每行仅使用一种编码

fix_latin在角色级别上起作用。如果已知每一行完全使用 UTF-8、iso-8859-1、cp1252 或 US-ASCII 之一进行编码,则可以通过检查该行是否是有效的 UTF-8 来使该过程更加可靠。

$ perl -e'
   use Encode qw( decode );
   for $bytes ("\xD0 \x92 \xD0\x92\n", "\xD0\x92\n") {
      if (!eval {
         $text = decode("UTF-8", $bytes, Encode::FB_CROAK|Encode::LEAVE_SRC);
         1  # No exception
      }) {
         $text = decode("cp1252", $bytes);
      }

      printf("U+%v04X\n", $text);
   }
'
U+00D0.0020.2019.0020.00D0.2019.000A
U+0412.000A

采用启发式方法,但它们非常可靠。他们只会失败,如果all对于给定的行,以下选项正确:

  • 该行使用 iso-8859-1 或 cp1252 进行编码,

  • 至少其中之一
    [€‚▪„...†‡ˆ‰Š´ŒŽ‘’“”•–—~™š›œžŸ<NBSP>�£¤¥�§�©ª«�<SHY>®̿°±23´µ¶·¸1º»¼½⁄¿ÀÁÁÊÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷]
    存在于该行中,

  • 的所有实例
    [ÀÁÁÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞß]
    总是紧随其后的是其中之一
    [€‚▪„...†‡ˆ‰Š´ŒŽ‘’“”•–—~™š›œžŸ<NBSP>�£¤¥�§�©ª«�<SHY>® ́°±23´µ¶·¸1º»1/23¿],

  • 的所有实例
    [àáâãäåæçèééêëìíîï]
    总是紧随其后的是两个
    [€‚▪„...†‡ˆ‰Š´ŒŽ‘’“”•–—~™š›œžŸ<NBSP>�£¤¥�§�©ª«�<SHY>® ́°±23´µ¶·¸1º»1/23¿],

  • 的所有实例
    [ðñòóôõöö]
    后面总是紧接着三个
    [€‚▪„...†‡ˆ‰Š´ŒŽ‘’“”•–—~™š›œžŸ<NBSP>�£¤¥�§�©ª«�<SHY>® ́°±23´µ¶·¸1º»1/23¿],

  • None of
    [呸呸呸呸]
    存在于该行中,并且

  • None of
    [€‚▪„...†‡ˆ‰Š´ŒŽ‘’“”•–—~™š›œžŸ<NBSP>�£¤¥�§�©ª«�<SHY>® ́°±23´µ¶·¸1º»1/43¿]
    除了前面提到的之外,都存在于该行中。


Notes:

  • Encoding::FixLatin 安装命令行工具fix_latin转换文件,使用第二种方法编写一个文件会很简单。
  • fix_latin(函数和文件)可以通过安装来加速编码::FixLatin::XS http://search.cpan.org/perldoc?Encoding::FixLatin::XS.
  • 相同的方法可用于 UTF-8 与其他单字节编码的混合。可靠性应该相似,但也可能有所不同。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

修复同时包含 UTF-8 和 Windows-1252 的文件 的相关文章

随机推荐

  • netty ChannelInboundHandlerAdapter 将帧裁剪为 ~1500 字节

    我已经实现了一个服务器应用程序 它使用 netty 框架通过 ChannelInblundHandlerAdapter 读取传入的字节 如标题所示 我的问题是 我不定期地从客户端获取内容 我认为这些内容在 1 500 字节后被剪切 例如 在
  • OSGi 声明性服务的绑定顺序

    假设我使用 OSGi 声明性服务 并且我有一个服务 该服务具有多个带有策略 动态的引用 A 强制一元 B 强制一元 C 强制倍数 D 可选一元 E 可选的多个 当我的服务开始时 所有参考资料都可用 有没有办法控制bind的调用顺序 我想让
  • 即使在 webpack 配置中拆分后,供应商代码仍然位于 bundle.js 文件中

    使用下面的 webpack 配置 我仍然在 bundle js 文件中获取供应商代码 即使在代码分割之后 bundle js 的大小也保持不变 我希望供应商代码不应出现在bundle js 中 遵循某些链接 但没有帮助 https gith
  • 使用 array_map() 访问第一级键,而不调用 `array_keys()`

    有没有办法做这样的事情 test array array first key gt first value second key gt second value var dump array map function a b return
  • 如何在 D3 中重用两个(或更多)链式转换序列

    我必须应用两个非常长的链式转换序列 它们主要在转换顺序上有所不同 并且我正在寻找一种紧凑的编码方式 作为一个玩具示例 考虑序列顺序应该是的情况a b c d e f g h and e f g h a b c d 我已经尝试使用下面的代码
  • AudioQueue内存播放示例

    有人知道使用 AudioQueue 从内存源播放的任何示例吗 我可以从文件中找到播放的所有示例 使用 AudioFileReadPackets 但在我的特定情况下 我自己实时生成数据 因此理想情况下 我想自己将数据排入队列 而不是使用回调将
  • 在开发期间清除 Rails 会话

    如何清除 Rails 会话以便我可以重新开始 我知道我可以用以下方法使每个会话变量无效session my var nil 但是是否有 rake 任务或知道如何将会话数据恢复为其最基本形式的任务 我在用着Spree http demo sp
  • phpMyadmin 数据库导入错误 #1046 - 未选择数据库

    我有一个从另一台计算机上的 phpmyadmin 导出的 sql 文件 我尝试在此计算机上导入该文件 但收到此错误 Error SQL查询 Database phplogin Table structure for table people
  • 如何让div居中对齐?

    我想要一个垂直和水平居中的 div 即位于页面的中心 我尝试了position absolute并将div的右上角左下角设置为0 但问题是 当我放大页面时 它与其他标题和其他 div 重叠 请帮我 如何在放大页面时将 div 定位在页面中心
  • C# 控制台应用程序 - 如何始终从控制台读取输入?

    我目前正在编写一个使用大量多线程的控制台应用程序 我希望能够始终允许用户在控制台中输入内容 但是 线程会定期输出到控制台 但我希望用户始终能够在控制台中输入内容 并由我来处理输入 我将如何实现这一目标 我在网上没有找到任何相关内容 先谢谢了
  • 如何使用 Java 将 JPEG 图像读入 BufferedImage 对象

    这不是一个重复的问题 因为我已经在Google和StackOverflow中寻找解决方案很长时间了 但仍然找不到解决方案 我有这两张图片 这是来自同一网站的两张图像 具有相同的前缀和相同的格式 唯一的区别是尺寸 第一个较大 而第二个较小 我
  • 导航栏链接到子文件夹

    每当我有一个指向子文件夹中页面的链接时 它就会冻结子文件夹中的导航栏 以便浏览器链接保留在子文件夹中并且无法找到 在 Visual Studio Express 中使用母版页 母版页如下所示
  • EAGL:它到底代表什么?

    我忘了 但是 EAGL 代表什么具体的东西吗 或者它只是核心动画 OpenGL 命名约定的一部分 CAEAGLLayer 等 AGL 是苹果 OS X 的 OpenGL 扩展的名称 我相信 EAGL 是 Embedded AGL 或 ES
  • 为什么使用map、forEach和for循环插入数据库时​​数组的顺序不同

    我有一个数组 1 2 3 4 5 当插入数据库时 我除了收到数据库中的 1 2 3 4 5 这样的结果之外 但只有循环 for 才能给我预期的结果 map 和 forEach 总是给我无序数组 如 1 3 4 5 2 或 4 3 2 5 1
  • EXC_BAD_INSTRUCTION(代码=EXC_I386_INVOP,子代码=0x0)

    我真的不明白为什么我有这个错误 首先 调试器停在机器代码处 该线程也没有显示任何内容 程序实际上没有代码就停止了 所以和 dispatch worker thread有关系 那是什么 有什么办法我可以调试这个吗 我应该回滚吗 当您运行 CP
  • pip ImportError:无法从“集合”导入名称“映射”

    pip 尝试访问的 python 库似乎存在冲突 如以下错误所示 root fedora user pip Traceback most recent call last File usr local bin pip line 5 in
  • Format-Table 根据输出缓冲区宽度设置列宽

    我有一个使用的 cmdletFormat Table输出可能很长的字符串 例如注册表路径 我想将每列宽度设置为输出缓冲区宽度除以列数 Example function Write Something CmdletBinding param
  • cassandra 列族数量的增加对堆利用率有什么影响?

    我们使用的是 cassandra 1 1 出于某些优化目的 我们决定增加键空间中的列族数量 对堆利用率有影响吗 Cassandra 是否有可能耗尽内存 根据 Cassandra Wiki 每个节点 消耗的堆大小定义为 memtable th
  • 无法读取 Angular 2 嵌套调用中未定义的属性“订阅”

    我想订阅company list component on getCompanies 来自company service 但是我收到以下错误 无法读取未定义的属性 订阅 这是代码 公司 service ts getCompaniesOfUs
  • 修复同时包含 UTF-8 和 Windows-1252 的文件

    我有一个生成 UTF 8 文件的应用程序 但某些内容的编码不正确 一些字符被编码为 iso 8859 1 又名 iso latin 1 或 cp1252 又名 Windows 1252 有没有办法恢复原文 Yes 显然 最好修复创建文件的程