字符串 -- 不可改变的序列

如同大多数高级编程语言一样,变长字符串是 Python 中的基本类型。Python 在“后台”分配内存以保存字符串(或其它值),程序员不必为此操心。Python 还有一些其它高级语言没有的字符串处理功能。

在 Python 中,字符串是“不可改变的序列”。尽管不能“按位置”修改字符串(如字节组),但程序可以引用字符串的元素或子序列,就象使用任何序列一样。Python 使用灵活的“分片”操作来引用子序列,字符片段的格式类似于电子表格中一定范围的行或列。以下交互式会话说明了字符串和字符片段的的用法:

字符串和分片 >>> s =

"mary had a little lamb"

>>> s[0]

# index is zero-based

'm'

>>> s[3] =

'x'

# changing element in-place fails

Traceback (innermost last):

File

"", line 1,

in

?

TypeError: object doesn't support item assignment

>>> s[11:18]

# 'slice' a subsequence

'little '

>>> s[:4]

# empty slice-begin assumes zero

'mary'

>>> s[4]

# index 4 is not included in slice [:4]

' '

>>> s[5:-5]

# can use "from end" index with negatives

'had a little'

>>> s[:5]+s[5:]

# slice-begin & slice-end are complimentary

'mary had a little lamb'

另一个功能强大的字符串操作就是简单的 in 关键字。它提供了两个直观有效的构造:

in 关键字 >>> s =

"mary had a little lamb"

>>>

for

c

in

s[11:18]:

print

c,

# print each char in slice

...

l i t t l e

>>>

if

'x'

in

s:

print

'got x'

# test for char occurrence

...

>>>

if

'y'

in

s:

print

'got y'

# test for char occurrence

...

got y

在 Python 中,有几种方法可以构成字符串文字。可以使用单引号或双引号,只要左引号和右引号匹配,常用的还有其它引号的变化形式。如果字符串包含换行符或嵌入引号,三重引号可以很方便地定义这样的字符串,如下例所示:

三重引号的使用 >>> s2 =

"""Mary had a little lamb

... its fleece was white as snow

... and everywhere that Mary went

... the lamb was sure to go"""

>>>

print

s2

Mary had a little lamb

its fleece was white as snow

and

everywhere that Mary went

the lamb was sure to go

使用单引号或三重引号的字符串前面可以加一个字母 "r" 以表示 Python 不应该解释规则表达式特殊字符。例如:

使用 "r-strings" >>> s3 =

"this \n and \n that"

>>>

print

s3

this

and

that

>>> s4 = r

"this \n and \n that"

>>>

print

s4

this \n

and

\n that

在 "r-strings" 中,可能另外组成换码符的反斜杠被当作是常规反斜杠。在以后的规则表达式讨论中会进一步说明这个话题。

文件和字符串变量

我们谈到“文本处理”时,我们通常是指处理的内容。Python 将文本文件的内容读入可以操作的字符串变量非常容易。文件对象提供了三个“读”方法: .read()、.readline() 和 .readlines()。每种方法可以接受一个变量以限制每次读取的数据量,但它们通常不使用变量。 .read() 每次读取整个文件,它通常用于将文件内容放到一个字符串变量中。然而 .read() 生成文件内容最直接的字符串表示,但对于连续的面向行的处理,它却是不必要的,并且如果文件大于可用内存,则不可能实现这种处理。

.readline() 和 .readlines() 非常相似。它们都在类似于以下的结构中使用:

Python .readlines() 示例 fh = open(

'c:\\autoexec.bat')

for

line

in

fh.readlines():

print

line

.readline() 和 .readlines() 之间的差异是后者一次读取整个文件,象 .read() 一样。.readlines() 自动将文件内容分析成一个行的列表,该列表可以由 Python 的 for ... in ... 结构进行处理。另一方面,.readline() 每次只读取一行,通常比 .readlines() 慢得多。仅当没有足够内存可以一次读取整个文件时,才应该使用 .readline()。

如果正在使用处理文件的标准模块,可以使用 cStringIO 模块将字符串转换成“虚拟文件”(如果需要生成模块的子类,可以使用 StringIO 模块,初学者未必要这样做)。例如:

cStringIO 模块 >>>

import

cStringIO

>>> fh = cStringIO.StringIO()

>>> fh.write(

"mary had a little lamb")

>>> fh.getvalue()

'mary had a little lamb'

>>> fh.seek(5)

>>> fh.write(

'ATE')

>>> fh.getvalue()

'mary ATE a little lamb'

但是,请记住,cStringIO“虚拟文件”不是永久的,这一点与真正的文件不同。如果不保存它(如将它写入一个真正的文件,或者使用 shelve 模块或数据库),则程序结束时,它将消失。

标准模块:string

string 模块也许是 Python 1.5.* 标准发行版中最常用的模块。实际上,在 Python 1.6 或更高版本中,string 模块中的功能将作为内置字符串方法(在撰写本文时,详细信息尚未发布)。当然,任何执行文本处理任务的程序也许应该用以下这行开头:

开始使用 string 的方法

import string

一般经验法则告诉我们,如果 可以 使用 string 模块完成任务,那么那就是 正确 的方法。与 re(规则表达式)相比,string 函数通常更快速,大多数情况下他们更易于理解和维护。第三方 Python 模块,包括某些用 C 编写的快速模块,适用于专门的任务,但可移植性和熟悉性都建议只要可能就使用 string。如果您习惯于使用其它语言,也会有例外,但不如您想像的那样多。

string 模块包含了几种类型的事物,如函数、方法和类;它还包含了公共常量的字符串。例如:

string 用法例 1 >>>

import

string

>>> string.whitespace

'\011\012\013\014\015 '

>>> string.uppercase

'ABCDEFGHIJKLMNOPQRSTUVWXYZ'

虽然可以用手写出这些常量,string 版本或多或少确保了常量对于运行 Python 脚本的国家语言和平台将是正确的。

string 还包括了以常见方式(可以结合这些方式来构成几种罕见的转换)转换字符串的函数。例如:

string 用法例 2 >>>

import

string

>>> s =

"mary had a little lamb"

>>> string.capwords(s)

'Mary Had A Little Lamb'

>>> string.replace(s,

'little',

'ferocious')

'mary had a ferocious lamb'

还有许多没有在这里具体说明的其它转换;可以在 Python 手册中查找详细信息。

还可以使用 string 函数来报告字符串属性,如子串的长度或位置,例如:

string 用法例 3 >>>

import

string

>>> s =

"mary had a little lamb"

>>> string.find(s,

'had')5>>> string.count(s,

'a')4

最后,string 提供了非常 Python 化的奇特事物。.split() 和 .join() 对提供了在字符串和字节组之间转换的迅捷方法,您会发现它们非常有用。用法很简单:

string 用法例 4 >>>

import

string>>> s =

"mary had a little lamb"

>>> L = string.split(s)

>>> L

[

'mary',

'had',

'a',

'little',

'lamb']

>>> string.join(L,

"-")

'mary-had-a-little-lamb'

当然,除了 .join() 之外,也许会利用列表来做其它事(如某些涉及我们熟悉的 for ... in ... 结构的事情)。

标准模块:re

re 模块废弃了在老的 Python 代码中使用的 regex 和 regsub 模块。虽然相对于 regex 仍然有几个有限的优点,不过这些优点微不足道,不值得在新代码中使用。过时的模块可能会从未来的 Python 发行版中删除,并且 1.6 版可能有一个改进的接口兼容的 re 模块。所以,规则表达式仍将使用 re 模块。

规则表达式很复杂。也许有人会撰写关于这个主题的书,但实际上,已经有许多人这样做了!本文尝试捕捉规则表达式的“完全形态”,让读者可以掌握它。

规则表达式是一种很简练方法,用于描述可能在文本中出现的模式。是否会出现某些字符?是否按特定顺序出现?子模式是否会重复一定次数?其它子模式是否会排除在匹配之外?从概念上说,似乎不能用自然语言了直观地描述模式。诀窍是使用规则表达式的简洁语法来编码这种描述。

当处理规则表达式时,将它作为它自己的编程问题来处理,即使只涉及一或两行代码;这些行有效地构成了一个小程序。

从最小处着手。从最基本上看,任何规则表达式都涉及匹配特定的“字符类”。最简单的字符类就是单个字符,它在模式中只是一个字。通常,您希望匹配一类字符。可以通过将类括在方括号内来表明这是一个类;在括号中,可以有一组字符或者用破折号指定的字符范围。还可以使用许多命名字符类来确定您的平台和国家语言。以下是一些示例:

字符类 >>>

import

re

>>> s =

"mary had a little lamb"

>>>

if

re.search(

"m", s):

print

"Match!"

# char literal

Match!

>>>

if

re.search(

"[@A-Z]", s):

print

"Match!"

# char class

...

# match either at-sign or capital letter

...

>>>

if

re.search(

"\d", s):

print

"Match!"

# digits class

...

可以将字符类看作是规则表达式的“原子”,通常会将那些原子组合成“分子”。可以结合使用 分组和 循环 来完成此操作。由括号表示分组:括号中包含的任何子表达式都被看作是用于以后分组或循环的原子。循环则由以下几个运算符中的某一个来表示:"*" 表示“零或多”;"+" 表示“一或多”;"?" 表示“零或一”。例如,请看以下示例:

样本规则表达式

ABC([d-w]*\d\d?)+XYZ

对于要匹配这个表达式的字符串,它必须以 "ABC" 开头、以 "XYZ" 结尾 -- 但它的中间必须要有什么呢?中间子表达式是 ([d-w]*\d\d?),而且后面跟了“一或多”运算符。所以,字符串的中间必须包括一个(或者两个,或者一千个)与括号中的子表达式匹配的字符或字符串。字符串 "ABCXYZ" 不匹配,因为它的中间没有必要的字符。

不过这个内部子表达式是什么呢?它以 d-w 范围内的 零或多个 字母开头。一定要注意:零字母是有效匹配,虽然使用英语单词 "some"(一些)来描述它,可能会感到很别扭。接着,字符串必须 恰好有一个数字;然后有 零或一个 附加数字。(第一个数字字符类没有循环运算符,所以它只出现一次。第二个数字字符类有 "?" 运算符。)总而言之,这将翻译成“一个或两个数字”。以下是一些与规则表达式匹配的字符串:

匹配样本表达式的字符串 ABC1234567890XYZ

ABCd12e1f37g3XYZ

ABC1XYZ

还有一些表达式与规则表达式 不匹配(想一想,它们为什么不匹配):

不匹配样本表达式的字符串 ABC123456789dXYZ

ABCdefghijklmnopqrstuvwXYZ

ABcd12e1f37g3XYZ

ABC12345%67890XYZ

ABCD12E1F37G3XYZ

需要一些练习才能习惯创建和理解规则表达式。但是,一旦掌握了规则表达式,您就具有了强大的表达能力。也就是说,转而使用规则表达式解决问题通常会很容易,而这类问题实际上可以使用更简单(而且更快速)的工具,如 string,来解决。

python print文本和数字混合_详解Python中的文本处理相关推荐

  1. python正则匹配空格+数字+空格_详解Python中正则匹配TAB及空格的小技巧

    详解Python中正则匹配TAB及空格的小技巧 发布时间:2020-10-15 08:38:48 来源:脚本之家 阅读:94 作者:杰瑞26 在正则中,使用.*可以匹配所有字符,其中.代表除\n外的任 ...

  2. python调用cmd命令释放端口_详解python调用cmd命令三种方法

    目前我使用到的python中执行cmd的方式有三种 使用os.system("cmd") 该方法在调用完shell脚本后,返回一个16位的二进制数,低位为杀死所调用脚本的信号号码, ...

  3. python中有那几种赋值_详解Python列表赋值复制深拷贝及5种浅拷贝

    概述 在列表复制这个问题,看似简单的复制却有着许多的学问,尤其是对新手来说,理所当然的事情却并不如意,比如列表的赋值.复制.浅拷贝.深拷贝等绕口的名词到底有什么区别和作用呢? 列表赋值 # 定义一个新 ...

  4. python自己创建模块引用失败_详解Python import方法引入模块的实例 Python怎么import自己写的模块...

    python中 import导入模块失败的问题? python中的import引用不了模块我傻,为你傻;我痛,为你痛;深夜里,你是我一种惯性的回忆. 为什么我用from lianxi import*就 ...

  5. python爬取小说出现乱码_详解Python解决抓取内容乱码问题(decode和encode解码)

    一.乱码问题描述 经常在爬虫或者一些操作的时候,经常会出现中文乱码等问题,如下 原因是源网页编码和爬取下来后的编码格式不一致 二.利用encode与decode解决乱码问题 字符串在Python内部的 ...

  6. python os.path.exists 已存在_详解python os.path.exists判断文件或文件夹是否存在

    1.SocketServer模块编写的TCP服务器端代码 Socketserver原理图服务端:import SocketServer #导入SocketServer,多线程并发由此类实现 class ...

  7. python识别数字程序_详解python实现识别手写MNIST数字集的程序

    我们需要做的第⼀件事情是获取 MNIST 数据.如果你是⼀个 git ⽤⼾,那么你能够通过克隆这本书的代码仓库获得数据,实现我们的⽹络来分类数字 git clone https://github.co ...

  8. python随机生成数字列表_详解Python利用random生成一个列表内的随机数

    首先,需要导入random模块: import random 随机取1-33之间的1个随机数,可能重复: random.choice(range(1,34)) print得到一系列随机数,执行一次得到 ...

  9. python 提示按任意键退出_详解Python实现按任意键继续/退出的功能 python请按任意键继续 什么意思...

    请问python中如何实现按任意键继续效果.嗯,请问哪里有中文的手册下载吗?还有,小编试了,pause命令编译时不认啊,. python请按任意键继续 什么意思 pause命令就是按任意键继续,你按需 ...

  10. python哪些类型可以作为迭代器_详解Python迭代和迭代器

    我们将要来学习python的重要概念迭代和迭代器,通过简单实用的例子如列表迭代器和xrange. 可迭代 一个对象,物理或者虚拟存储的序列.list,tuple,strins,dicttionary, ...

最新文章

  1. Redis最佳实践:7个维度+43条使用规范,带你彻底玩转Redis | 附实践清单
  2. eclipse取消不了多行注释_Eclipse常用快捷键
  3. plsql中导入csvs_在命令行中使用sql分析csvs
  4. 仿新浪微博滚动,无文字渐显功能
  5. (BFS)Meteor Shower (poj3669)
  6. 转!!URL和URI区别
  7. python cookbook 2字符串(2)
  8. Golang编程语言简介 go语言特点
  9. 解决 大漠测试工具 “你的系统没有发现大漠插件”问题
  10. linux将pdf转为png,将多页PDF转换为PNG并返回(Linux)
  11. 腾讯云域名如何绑定ip地址
  12. 大数据时代隐私泄露呈高发趋势 如何有效预防成关键
  13. Oracle不走索引hint,oracle不走hint原因1:依据hint会出现错误结果
  14. 高级语言?编译程序?解释程序?目标代码?
  15. Gitlab上传代码时报错文件太大无法上传
  16. Linux命令之查找命令
  17. Rotating Rings
  18. Uber打车用户留存情况预测
  19. Linux内核机制总结内存管理之内存耗尽杀手(二十四)
  20. spider pi 智能视觉六足机器人 巡路功能 0603

热门文章

  1. 并发测试工具Jmeter安装与简单使用
  2. 【从0到1搭建LoRa物联网】12、LoRa网关与平台通讯协议
  3. svn取消文件夹图标_SVN文件夹或文件不显示图标解决方法
  4. TDR土壤水分检测传感器方案设计
  5. 文献管理软件 EndNote20.1 for Windows版
  6. 北京航空航天计算机考研科目,2020考研北京航空航天大学计算机考研考试科目...
  7. 那些自媒体视频剪辑素材是怎么找到的?
  8. 数据结构——线性链表/单链表设计
  9. 计算机技术硬件基础.pdf,网络工程师辅导教程--计算机硬件基础知识部分.pdf
  10. 微信小程序:事件传参