python3之python的核心数据类型(字符串)
----------
字符串是用来记录文本信息的。 它们是在python中作为序列(也就是说,一个包含其他对象的有序集合)提到的第一个例子。序列中的元素包含了一个从左到右的顺序---序列中的元素根据它们的相对位置进行存储和读取。从严格意义上来说, 字符串是单个字符的字符串的序列,其他类型的序列还包括 列表和 元组。

序列的操作
作为序列,字符串支持假设其中各个元素包含位置顺序的操作。例如,如果我们有一个含有四个字符的字符串,我们通过内置的len函数验证其长度并通过索引操作得到其各个元素。

>>>S = 'Spam'
>>>len(S)
4
>>>S[0]
'S'
>>>S[1]
'p'

在python ,

索引是按照从最前面的偏移量进行编码的,也就是从0开始,第一项索引为0,第二项索引为1,依此类推。注意我们在这里是如何把字符串赋给一个名为S的变量的。我们随后将详细介绍这是如何做到的,但是,

python变量不需要提前声明。当给一个变量赋值的时候就创建了它,可能赋的是任何类型的对象,并且当变量出现在一个表达式中的时候,就会用其值替换它。在使用变量的值之前必须对其赋值。我们需要把一个对象赋给一个变量以便保存它供随后使用。

在python中,我们能够反向索引, 从最后一个开始(正向索引是从左边开始计算,反向索引是从右边开始计算)。

>>>S[-1]
'm'
>>>S[-2]
'a'


一般来说,负的索引号会简单地与字符串的长度相加,因此,以下两个操作是等效的。


>>>S[-1]
'm'
>>>S[len(S)-1]
'm'

值得注意的是,我们

能够在广括号中使用任意表达式,而不仅仅是使用数字常量---只要python需要一个值,我们可以使用一个常量、一个变量或任意表达式。python的语法在这方面是完全通用的。除了简单地从位置进行索引,序列也支持一种所谓分片(slice)的操作,这是一种一步就能够提取整个分片(slice)的方法。例如:


>>>S
'Spam'
>>>S[1:3]
'pa'

也许认识分片的最简单的办法就是把它们看做是从一个字符串中一步就提取出一部分的方法。

它们的一般形式为X[I:J], 表示"取出在X中从偏移为I,直到但不包括偏移量为J的内容"。 结果就是返回一个新的对象。 在一个分片中,左边界默认为0,并且右边界默认为分片序列的长度。这引入了一些常用法的变体:

>>>S[1:]
'pam'
>>>S
'Spam'
>>>S[0:3]
'Spa'
>>>S[:3]
'Spa'
>>>S[:-1]
'Spa'
>>>S[:]
'Spam'

最后,作为一个序列,

字符串也支持使用加号进行合并(将两个字符串合成一个新的字符串),或者重复(通过再重复一次创建一个新的字符串):


>>>S
'Spam'
>>>S+'xyz'
'Spamxyz'
>>>S
'Spamxyz'
>>>S*8
'SpamSpamSpamSpamSpamSpamSpamSpam'

注意

加号(+)对于不同的对象有不同的意义:对于数字为加法,对于字符串为合并。这是python的一般特性,也就是我们将会在本书后面提到的多态。简而言之,一个操作的意义取决于被操作的对象。正如将在学习动态类型时看到的那样,这种多态的特性给python代码带来了很大的简洁性和灵活性。



不可变性


注意:在之前的例子中,没有通过任何操作对原始的字符串进行改变。每个字符串都被定义为生成新的字符串作为其结果,因为

字符串在python中具有不可变性--- 在创建后不能就地改变。例如,不能通过对其某一位置进行赋值而改变字符串,但是你总是可以通过建立一个新的字符串并以同一个变量名对其进行赋值。因为python在运行过程中会清理


旧的对象。


>>>S
'Spam'
>>>S[0]='z'
...error text omitted...
TypeError: 'str' object does not support item assignment
>>>S='z'+S[1:]
>>>S
'zpam'

在Python中的每一个对象都可以分为不可变性或者可变性。在核心类型中,

数字、字符串和元组是不可变的; 列表和字典不是这样(它们可以完全自由地改变)。



类型特定的方法


目前我们学习过的每一个字符串操作都是一个真正的序列操作。也就是说,这些操作在python中的其他序列中也会工作,包括列表和元组。尽管这样,除了一般的序列操作,字符串还有独有的一些操作方法存在。例如,字符串的find方法是一个基本的子字符串查找操作(它将返回一个传入子字符串的偏移量,或者没有找到的情况下返回-1),而字符串的replace方法将会对全局进行搜索和替换。


>>>S.find('pa')
1
>>S
'Spam'
>>>S.replace('pa','XYZ')
'SXYZm'
>>>S
'Spam'

尽管这些字符串方法的命名有改变的含义,但在这里我们都不会改变原始的字符串,而是会创建一个新的字符串作为结果---因为字符串具有不可变性,我们必须这样做。字符串方法将是python中文本处理的头号工具。其他的方法还能够实现通过分隔符将字符串拆分为子字符串(作为一种解析的简单形式),大小写变换,测试字符串的内容(数字、字母或其他),去掉字符串后的空格字符。


>>>line='aaa.bbb.ccccc.dd'
>>>line.split(',')
['aaa','bbb','ccccc','dd']
>>>S='spam'
>>>S.upper()
'SPAM'
>>>S.isalpha()
True
>>>line='aaa.bbb,ccccc,dd\n'
>>>line=line.rstrip()
>>>line
'aaa,bbb,ccccc,dd'

字符串还支持一个叫做格式化的高级替代操作,可以以一个表达式的形式(最初的)和一个字符串方法调用(python2.6和python3.0中新引入的)形式使用:


>>>'%s,eggs,and %s' % ('spam','SPAM!')
'spam,eggs,and SPAM!'
>>>'{0},eggs,and {1}'.format('spam','SPAM!')
'spam,eggs,and SPAM!'

注意:尽管序列操作是通用的,但方法不通用(虽然某些类型共享某些方法名,字符串的方法只能用于字符串)。一条简明的法则是这样的:

可作用于多种类型的通用型操作都是以内置函数或表达式的形式出现的[例如,len(X),X[0]],但是类型特定的操作是以方法调用的形式出现的[例如,aString.upper()]。如果经常使用python,你会顺利地从这些分类中找到你所需要的工具。



寻求帮助


上一节介绍的方法很具有代表性,但是仅仅是少数的字符串的例子而已。对于更多细节,你可以

调用内置的dir函数,将会返回一个列表,其中包含了对象的所有属性。由于方法是函数属性,它们也会在这个列表中出现。


>>>dir('aaa')

dir函数简单地给出了方法的名称。要查询它们是做什么的,你可以将其传递给help函数。


>>>help('aaa'.replace)


help是一个随python一起分发的面向系统代码的接口。另外你也能够对整个字符串提交查询,如: help('aaa'),一般最好去查询一个特定的方法,就像我们上边一样。



编写字符串的其它方法


到目前为止,我们学习了字符串对象的序列操作方法和类型特定的方法。python还提供了各种编写字符串的方法,我们将会在下面进行更深入的介绍。例如,反斜线转义序列表示特殊的字符。


>>>S='a\nB\tC'
>>>len(S)
5
>>>ord('\n')
10
>>>S='A\oB\oC'
>>>len(S)
5


python允许字符串包括在单引号或双引号中(它们代表着相同的东西)。 它也允许在三个引号(单引号或双引号)中包括多行字符串常量。当采用这种形式的时候,所有的行都合并在一起,并在每一行的末尾增加换行符。这是一个微妙的语法上的便捷方式,但是在python脚本中嵌入像HTML或XML这样的内容时,这是很方便的。


>>>msg="""aaaaaaaaaaa
bbbb'''bbbbbb""bbbbbb'bbbb
ccccccccccc"""
>>>msg
'\naaaaaaaaaa\nbbb\'\'\'bbbbbbbbb""bbbbbb\'bbbb\nccccccccccccc'



模式匹配


值得关注的一点就是字符串对象的方法能够支持基于模式的文本处理。文本的模式匹配是本书范围之外的一个高级工具,但是有其他脚本语言背景的读者也许对在python中进行模式匹配很感兴趣,

我们需要导入一个名为re的模块。这个模块包含了类似搜索、分割和替换等调用。


>>>import re
>>>match=re.match("Hello[\t]*(.*)world',"Hello Python world')
>>>match.group(1)
"python '

这个例子的目的是搜索子字符串,这个子字符串以"Hello"开始,后面跟着零个或几个制表符或空格,接着有任意字符并将其保存到匹配的group中,最后以"world"结尾。如果找到了这样的子字符串,与模式中括号包含的部分匹配的子字符串的对应部分保存为组.如例:


>>>match=re.match('/(.*)/(.*)/(.*)','/usr/home/lumberjack')
>>>match.groups()
('usr','home','lumberjack')

模式匹配本身是一个相当高级的文本处理工具,但是在python中还支持更高级的语言处理工作,包括自然语言处理等。