首页 > 解决方案 > ± 在 python 中的正则表达式中

问题描述

我正在用 python 2.7 做正则表达式。

我的文档有一个字符串"INL±1LSB",我试图找到这个字符串并打印1LSB

我试过这个命令:

strings = re.findall(r'INL(?:\xb1)(1LSB)', f.read())
print (strings)

但它找不到。(打印的结果是[])。

但是当我将文档中的字符串更改为"±1LSB"并使用以下命令时:

strings = re.findall(r'(?:\xb1)(1LSB)', f.read())
print (strings)

输出将是['1LSB']

我认为问题在于它在±之前找不到任何字符。

我应该怎么做才能解决这个问题?

标签: pythonregexpython-2.7

解决方案


您的文档具有INL±1LSB以 UTF-8 编码的字符串,但您正试图匹配以 Latin-1(或某些近亲)编码的相同字符串。通常,编码问题比这要明显得多,但是您设法找到了一个特别阴险且容易混淆的问题。

但首先,解决方案:要么

  • 更改您的正则表达式以使用 UTF-8 编码而不是 Latin-1 编码,因此它与搜索字节匹配,或者
  • decode('utf8')字节并使用 Unicode 而不是字节正则表达式搜索它们。

解释:

在 UTF-8 中,±字符被编码为两个字节,\xc2\xb1. 在 Latin-1 中,它被编码为单个字节,\xb1. 这恰好与 UTF-8 的第二个字节相同。这种情况只发生在 Latin-1 末尾的一小部分字符上,其中大部分不常用,所以大多数人在被它咬之前才知道这不是一个陷阱。

如果您在字节中搜索\xb1LSB,它将匹配,就像在 Latin-1 中一样,匹配一半字符。但是,如果您搜索它们INL\xb1,它将失败,这就是您要问的问题。

您可能会发现问题的唯一方法是,如果您采用 decode-everything-to-Unicode 路线(这通常是这种情况;这就是 Python 3 旨在鼓励您尽可能解码所有内容的原因)。


推荐阅读