博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
《Python Cookbook(第2版)中文版》——1.11 检查一个字符串是文本还是二进制
阅读量:6564 次
发布时间:2019-06-24

本文共 1886 字,大约阅读时间需要 6 分钟。

本节书摘来自异步社区《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 stringtext_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环境下时,这种做法才有意义。

转载地址:http://wcjjo.baihongyu.com/

你可能感兴趣的文章
疑似checkpoint堵塞数据库连接
查看>>
Node.js中针对中文的查找和替换无效的解决方法
查看>>
理解指针的关键
查看>>
如何查看Ubuntu下已安装包版本号
查看>>
我的那些年(2)~我毕业了
查看>>
VS2017 配置ImageMagick
查看>>
Hive任务优化--控制hive任务中的map数和reduce数
查看>>
[摄影]上海往事
查看>>
【Leetcode】Search in Rotated Sorted Array
查看>>
redis3.0.0 集群安装详细步骤
查看>>
FutureTask——另一种闭锁的实现
查看>>
Linux 用户和用户组管理
查看>>
tomcat架构分析(valve源码导读)
查看>>
spring中InitializingBean接口使用理解(转)
查看>>
基于php5.5使用PHPMailer-5.2发送邮件
查看>>
InstallShield 2012 Spring新功能试用(16): Suite/Advanced UI 或 Advanced UI安装程序能在安装时进行输入合法性校验与反馈...
查看>>
C#面试宝典
查看>>
基金项目的英文
查看>>
《软件性能测试与LoadRunner实战教程》喜马拉雅有声图书上线
查看>>
ios 字典转模型
查看>>