【问题标题】:Python regex against Latin-1 character encoding?Python正则表达式反对Latin-1字符编码?
【发布时间】:2023-04-05 02:08:02
【问题描述】:

我有一个包含(我相信)latin-1 编码的文件。

但是,我无法将正则表达式与此文件匹配。

如果我 cat 文件,它看起来很好:

但是,我找不到字符串:

In [12]: txt = open("b").read()

In [13]: print txt
  <Vw_IncidentPipeline_Report>


In [14]: txt
Out[14]: '\x00 \x00 \x00<\x00V\x00w\x00_\x00I\x00n\x00c\x00i\x00d\x00e\x00n\x00t\x00P\x00i\x00p\x00e\x00l\x00i\x00n\x00e\x00_\x00R\x00e\x00p\x00o\x00r\x00t\x00>\x00\r\x00\n'

In [22]: txt.find("Vw_IncidentPipeline_Report")
Out[22]: -1

In [23]: txt.decode("latin-1")
Out[23]: u'\x00 \x00 \x00<\x00V\x00w\x00_\x00I\x00n\x00c\x00i\x00d\x00e\x00n\x00t\x00P\x00i\x00p\x00e\x00l\x00i\x00n\x00e\x00_\x00R\x00e\x00p\x00o\x00r\x00t\x00>\x00\r\x00\n'

In [25]: txt.decode("utf-16le")
Out[25]: u'\u2000\u2000\u3c00\u5600\u7700\u5f00\u4900\u6e00\u6300\u6900\u6400\u6500\u6e00\u7400\u5000\u6900\u7000\u6500\u6c00\u6900\u6e00\u6500\u5f00\u5200\u6500\u7000\u6f00\u7200\u7400\u3e00\u0d00\u0a00'

如何成功解码字符串,以便在其中找到字符串?

【问题讨论】:

  • 文件开头是否有字节序标记('\xff\xfe''\xfe\xff')?
  • 除非 OP 编辑​​了上述脚本,否则文件显然是尖叫的 (a) 以 UTF-16BE 编码 (b) 开头没有 BOM。

标签: python encoding utf-8 character-encoding


【解决方案1】:

不是 Latin-1,而是 utf-16 大端:

>>> txt = '\x00 \x00 \x00<\x00V\x00w\x00_\x00I\x00n\x00c\x00i\x00d\x00e\x00n\x00t\x00P\x00i\x00p\x00e\x00l\x00i\x00n\x00e\x00_\x00R\x00e\x00p\x00o\x00r\x00t\x00>\x00\r\x00\n'
>>> txt.decode("utf-16be")
u'  <Vw_IncidentPipeline_Report>\r\n'

所以,就这样解码,从此过上幸福的生活;-)。

【讨论】:

  • 你不是说“它不是 Latin-1”吗?
  • 其实我觉得是utf-16le。带有 utf-16be 的 iconv 给出了日语。
  • @Joseph,您是否可能在文件中使用了带有 python 转义码的 iconv?如果您使用的是 iconv,则需要将 \x00 替换为 NUL 字节
  • @Bob,是的,我的意思是 Latin-1、tx、+1。 @Joseph,你错了:它用 BE 解码很好,用 LE 解码不好(正如你已经展示的那样),那么你为什么不这么认为呢?如果您想使用 iconv 而不是 Python,为什么要标记您的问题“python”,顺便说一句?
【解决方案2】:

您的编码错误。试试txt.decode("UTF-16BE")

让我们检查一下 iconv...

>>> txt='\x00 \x00 \x00<\x00V\x00w\x00_\x00I\x00n\x00c\x00i\x00d\x00e\x00n\x00t\x00P\x00i\x00p\x00e\x00l\x00i\x00n\x00e\x00_\x00R\x00e\x00p\x00o\x00r\x00t\x00>\x00\r\x00\n'
>>> open("txt","w").write(txt)
>>> exit()
$ iconv -f utf-16be txt
  <Vw_IncidentPipeline_Report>

不,这里没有日语

【讨论】:

  • 其实我觉得是utf-16le。带有 utf-16be 的 iconv 给出了日语。
  • @Joseph,iconv 对我来说很好用。你能告诉我们你是怎么学日语的吗?
【解决方案3】:

可能是 UTF-8。你的正则表达式是什么?

【讨论】:

  • 不,不是所有的\x00s,不可能是utf-8。根据我的回答,从未见过更清晰的 UTF-16 大端编码。
  • 从技术上讲,数据有效的 UTF-8。但是谁用 U+0000 和 ASCII 字符交替写入文件呢?
【解决方案4】:

你可以试试chardet模块,看看你对编码的判断是否正确。

【讨论】:

  • 你显然没有尝试过。 chardet 被记录为与带有 BOM 的 UTF-16xE 一起使用,否则。这是尝试的结果: >>> chardet.detect(txt) {'confidence': 1.0, 'encoding': 'ascii'} >>>
  • 字节顺序标记:Unicode 可以编码为 16 位或 32 位整数,因此您必须知道使用哪种编码
  • 这是一个字节顺序标记,而不是代码大小标记。主要目的是标记整数是以 bigendian 顺序还是 littleendian 顺序表示的。见http://en.wikipedia.org/wiki/Byte_order_mark
【解决方案5】:

其实是UTF-18LE,所以我用了:

iconv -f 'UTF-16LE//' -t utf-8 -c

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-01-15
    • 2020-07-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-11
    • 2019-12-09
    相关资源
    最近更新 更多