《Python Cookbook(第2版)中文版》——1.11 检查一个字符串是文本还是二进制

简介:

本节书摘来自异步社区《Python Cookbook(第2版)中文版》一书中的第1章,第1.11节,作者[美]Alex Martelli , Anna Martelli Ravenscrof , David Ascher ,高铁军 译,更多章节内容可以访问云栖社区“异步社区”公众号查看。

1.11 检查一个字符串是文本还是二进制

任务

在Python中,普通字符串既可以容纳文本,也可以容纳任意的字节,现在需要探知(当然,完全是启发式的试探:对于这个问题并没有什么精准的算法)一个字符串中的数据究竟是文本还是二进制。

解决方案

我们采取Perl的判定方法,如果字符串中包含了空值或者其中有超过30%的字符的高位被置1(意味着该字符的码值大于126)或是奇怪的控制码,我们就认为这段数据是二进制数据。我们得自己编写代码,其优点是对于特殊的程序需求,我们随时可以调整这种启发式的探知方式:

from _ _future_ _ import division           # 确保/不会截断
import string
text_characters = "".join(map(chr, range(32, 127))) + "\n\r\t\b"
_null_trans = string.maketrans("", "")
def istext(s, text_characters=text_characters, threshold=0.30):
      # 若s包含了空值,它不是文本
      if "\0" in s:
             return False
      # 一个“空”字符串是“文本”(这是一个主观但又很合理的选择)
      if not s:
            return True
      # 获得s的由非文本字符构成的子串
      t = s.translate(_null_trans, text_characters)
      # 如果不超过30%的字符是非文本字符,s是字符串
      return len(t)/len(s) <= threshold

讨论

可以轻易地修改函数istext的启发式探知部分,只需传递一个指定的阀值作为判断某字符串所含数据是“文本”(即正常的ASCII字符加上4个“正常”的控制码,在文本中这几个控制码都是有意义的)的基准,默认的阀值是0.30(30%)。举个例子,如果期望它是采用了iso-8859-1的意大利文本,可以给text_characters参数添加意大利语中的一些重音字母,“àèéìòù”。

很多时候,需要检查的对象是文件,而不是字符串,也就是说要判断文件中的内容是文本还是二进制数据。同样地,我们仍可采用Perl的启发式方法,用前面提供的istext函数来检查文件的第一个数据块:

def istextfile(filename, blocksize=512, **kwds):
     return istext(open(filename).read(blocksize), **kwds)

注意,默认情况下,istext函数中的len(t)/len(s)将被截断成0,因为这是一个整数之间的除法结果。以后的版本(估计是Python 3.0,几年后发布),Python中的/操作符的意义会被改变,这样我们在做除法运算的时候就不会发生截断—如果你确实需要截断,可以用截断除法操作符//。

不过,现在Python还没有改变除法的语义,这是为了保证一定的向后兼容性。为了让成千上万行的现有的Python程序和模块平滑地工作于所有的Python 2.x版本,这非常重要。不过,对于语言版本的主版本号的改变,Python允许进行不考虑向后兼容性的改变。

因此,对于本节的解决方案中的模块,按照未来版本中计划的行为模式来改变除法的行为是非常方便的,我们用这种方式来引入模块:

from _ _future_ _ import division

这条语句并不影响程序的其余部分,只影响紧随此声明的模块;通过这个模块,/表现得像“真实的除法”(没有截断)。对于Python 2.3和2.4,dvision可能是唯一需要从 _future _导入的模块。其他的一些未来版本中计划的特性,nested_scope和生成器,现在已经是语言的一部分了,因而无法被关闭—当然明确导入它们没有什么坏处,但只有在你的程序需要能够运行在老版本的Python环境下时,这种做法才有意义。

相关文章
|
1天前
|
Python
Python避免在字符串和字节之间混淆
【5月更文挑战第5天】Python避免在字符串和字节之间混淆
11 3
|
1天前
|
机器学习/深度学习 自然语言处理 算法
Gensim详细介绍和使用:一个Python文本建模库
Gensim详细介绍和使用:一个Python文本建模库
10 1
|
2天前
|
数据安全/隐私保护 开发者 Python
【Python 基础】检查字符串是否只包含数字和字母?
【5月更文挑战第8天】【Python 基础】检查字符串是否只包含数字和字母?
|
2天前
|
Python
【Python 基础】如何将一个字符串转化为全大写和全小写?
【5月更文挑战第8天】【Python 基础】如何将一个字符串转化为全大写和全小写?
|
2天前
|
机器学习/深度学习 存储 人工智能
python 字符串的三种定义方式
python 字符串的三种定义方式
8 1
|
2天前
|
Python
python 二进制与字符编码详解
python 二进制与字符编码详解
7 0
|
4天前
|
Python Perl
Python中的字符串分析:判断字符串中是否包含字母
Python中的字符串分析:判断字符串中是否包含字母
10 0
|
9月前
|
自然语言处理 Python
Python读取Word/PPT文件文本内容和图片内容
读取某个指定路径下的Word/PPT文件,并将其中所有的文本内容生成一个TXT文件,将所有的图片内容保存在一个文件夹里
263 0
|
12月前
|
存储 Linux 测试技术
Python操作PDF-文本和图片提取(使用PyPDF2和PyMuPDF)
Python操作PDF-文本和图片提取(使用PyPDF2和PyMuPDF)
726 0
python小玩意——使用PIL模块将文本文字放在图片里面
python小玩意——使用PIL模块将文本文字放在图片里面
python小玩意——使用PIL模块将文本文字放在图片里面