【问题标题】:Python 3.6.3 vs 2.7.3 for regular expressions: same script different results正则表达式的 Python 3.6.3 与 2.7.3:相同的脚本不同的结果
【发布时间】:2018-01-25 11:25:52
【问题描述】:

我正在使用 Python 3.6.3 和 2.7.3 版本运行相同的脚本。该脚本在 2.7.3 中运行良好,但在 3.6.3 中却不行。似乎区别在于我的代码的正则表达式部分。

我正在为两个脚本版本在同一个外部文件中搜索一些字符串,将命中保存在列表中。结果列表的len() 对于两个版本是不同的。

我试图通过创建一个用于正则表达式的小文件来制作一个重现错误的 MWE,但是两个版本的 Python 都会产生相同的输出。我唯一的解决方案是提供原始文件。但这是一个相当长的文本文件,所以您可以从这里下载:https://ufile.io/jjc56 此文件有效期为 30 天。我认为这可能比将所有内容都粘贴到问题中更好。

这段代码重现了错误。

import re

inputfile = "opt-guess-firsttetint-r-h2o.out"
with open(inputfile,"r") as input_file:
    input_string = input_file.read()
    input_file.close()

match_geometry = list(re.findall('CARTESIAN COORDINATES \(ANGSTROEM\)(.*?)CARTESIAN COORDINATES \(A\.U\.\)', input_string, re.DOTALL))

match_energy = list(re.findall('FINAL SINGLE POINT ENERGY(.*?)-------------------------', input_string, re.DOTALL))

print(len(match_geometry))
print(len(match_energy))

使用 Python 3.6.3 输出:

78
77

使用 Python 2.7.3 输出:

188
188

比较:

$ grep "CARTESIAN COORDINATES (ANGSTROEM)" externalfile | wc -l
> 188

$ grep "FINAL SINGLE POINT ENERGY" externalfile | wc -l
> 188

如果您需要更多信息,请说出来!

【问题讨论】:

标签: python regex python-3.x python-2.7


【解决方案1】:

Python 2 和 Python 3 之间的主要区别在于文本处理:而在 Python 2 中,文本被视为与纯 C 中一样,即恰好匹配 32-128 范围内的 ASCII 字符的字节序列,这是不正确的对于 Python 3 - 假定文件中的字节采用某种文本编码,并在程序中处理之前解码为适当的 unicode 字符点。

同样,在 Python2 中,正则表达式默认作用于“字节字符串”,而在 Python 3 上则作用于文本字符串(在 Python 2 中,如果表达式和文本都是“unicode”对象,您也可以使用文本,而不是比'str')

我们需要更多上下文,但您的问题可能在于 Python 3 读取您的文本文件并假设编码不正确 - 例如,您的数据是 utf-8,但 Python 假设它为拉丁语 1 - 会读取字符超出 ASCII 范围是不正确的,不会给您错误,因为从 0-255 的所有字节都是有效的 Latin-1 - 但生成的 mojibake 将使正则表达式失败。

只需在读取数据时强制使用正确的encoding="..." 来匹配您的文件,您应该没问题。

仅供参考,会触发我上面描述的行为的一个字符是“Å” - 我认为在这种特殊情况下不太可能发生。

【讨论】:

  • 抱歉 - 在尝试您制作的文件时,我得到了 77 和 78 个与 Python 3、Python 2 和 grep 匹配的文件。我的主要假设是您只是在不知道的情况下对不同的文件进行了测量。您使用 grep 的“外部文件”是否与“opt-guess-firsttetint-r-h2o.out”相同?
  • 我刚刚下载了文件,我得到了 188 和 188 匹配 python 2.7.3 和 grep。我要等到明天早上上班的时候才能测试 python 3。
猜你喜欢
  • 1970-01-01
  • 2019-08-28
  • 2022-06-10
  • 1970-01-01
  • 1970-01-01
  • 2017-11-08
  • 2016-11-04
  • 1970-01-01
  • 2014-08-16
相关资源
最近更新 更多