字符串是一个有序的字符集合,用于存储和表现基于文本的信息。
常见的字符串常量和表达式
T1=‘’ 空字符串
T2="diege's" 双引号
T3="""...""" 三重引号块
T4=r'\temp\diege' Raw字符串 抑制(取消)转义,完全打印\tmp\diege,而没有制表符
T5=u’diege' Unicode字符串
T1+T2 合并
T1*3 重复
T2[i] 索引
T2[i:j] 分片
len(T2) 求长
"a %s parrot "% type 字符串格式化
T2.find('ie') 字符串方法调用:搜索
T2.rstrip() 字符串方法调用:移除空格
T2.replace('ie','efk') 字符串方法调用:替换
T2.split(',') 字符串方法调用:分割
T2.isdigit() 字符串方法调用:内容测试
T2.lower() 字符串方法调用:大写转换为小写
for x in T2: 迭代
'ie' in T2 成员关系
一、字符串常量
1、单双引号字符串是一样
Python自动在任意表达式中合并相邻的字符串常量。尽管可以在他们之间增加+操作符来明确表示这是一个合并操作。
>>> T2="Test " 'for ' "diege"
>>> T2
'Test for diege'
>>> T2="Test "+'for '+"diege"
>>> T2
'Test for diege'
不能在字符串之间增加逗号来连接,这样会创建一个元组而不是字符串。python倾向于打印所有这些形式字符串为单引号,除非字符串内有了单引号。
不过也可以通过反斜杠转义嵌入引号
>>> T2="Test "+'for '+"diege's"
>>> T2
"Test for diege's"
>>> 'diege\'s'
"diege's"
2、用转义序列代表特殊字节
\newline 忽视(连续)
\\ 反斜杠(保留\)
\' 单引号(保留')
\" 双引号(保留”)
\n 换行
\f 换页
\t 水平制表符
\v 垂直制表符
\b 倒退 前的字符没有了
\a 响铃
\r 返回 前面的字符没有了
\N{id} Unicode数据库ID
\uhhhh Unicode16位的十六进制值
\Uhhhh Unicode32位的十六进制值
\xhh 十六进制值
\ooo 八进制值
\0 NULL (不是字符串结尾)
\other 不转义(保留)
3、字符串抑制转义
myfile=open('C:\new\text.data','w')
这个调用会尝试打开C:(换行)ew(制表符)ext.data的文件,而不是期待的结果。
解决办法,使用raw字符串。如果字母r(大写或者小写)出现在字符串的第一个引号前面,它会关闭转义机制。
myfile=open(r'C:\new\text.data','w')‘
另外一个办法就是把\转义
myfile=open('C:\\new\\text.data','w')‘
4、三重引号编写多行字符串块
块字符串,编写多行文本数据便捷语法。
这个形式以三重引号开始(单双引号都可以),并紧跟任意行的数的代码,并且以开头同样的三重引号结尾。嵌入这个字符串文本中的单引号双引号也会但不是必须转义。三重引号字符串也常用在开发过程中作为一个种黑客风格的方法去废除一些代码。如果希望让一些代码不工作,之后再次运行代码,可以简单地在这几行前,后加入三重引号
X=10
"""
import os
print os.getcwd()
"""
Y=19
5、字符串编码更大的字符集
Unicode字符串有时称为“宽”字符串。因为每个字符串也许在内存会占用大于一个字节的空间。
Unicode字符串典型的应用于支持国际化的应用(i18)
通过在开头的引号前增加字母u(大小写都可以)编写一个Unicode字符串。
>>> T9=u'diege' #这种语法产生了一个unicode字符串对象。
>>> T9
u'diege'
>>> type(T9)
<type 'unicode'>
Python中允许表达式自由地混合Unicode字符串和一般字符串。并将混合类型的结果转为Unicode。
Unicode字符串也可以合并,索引,分片。通过re模块进行匹配,并且不能够进行实地修改。和一般字符串一样。
python同等对待一般字符串和Unicode字符串
如果需要在一般字符串和Unicode字符串中转换,可以使用内置的str和unicode函数
>>> str(u'diege')
'diege'
>>> unicode('diege')
u'diege'
unicode是用来处理多字节字符的,所以能够使用特殊的"\u","\U"转义字符串去编码大于8bit的二进制值
u'ab\x20cd'
sys模块包含了默认Unicode编码方案的获取以及设置的调用(默认往往是ASCII)
可以混合raw和Unicode字符串
二、实际应用的字符串
1、基本操作
字符串长度获取方法: 内置函数len()
>>> len('test')
4
字符串连接:+
>>> 'test'+'diege'
'testdiege'
python不允许+表达式混合字符串和数字。
字符串重复:*
>>> 'test'*3
'testtesttest'
用在分割提示
>>> print '-'*80
迭代:使用for语句在一个字符串中进行迭代
>>> for s in myname: print s
...
d
i
e
g
e
for 循环指派了一个变量去获取一个序列其中的的元素,并对每一个元素执行一个或多个语句。
成员关系测试:使用in表达式操作符进行成员关系测试。
>>> 'g' in myname
True
>>> 'k' in myname
False
2、索引和分片
字符串中的字符是通过索引(通过在字符串之后的方括号中提供所需的元素的数字偏移量提取的)将获得在特定位置的一个字符的字符串。
Ptyhon偏移量是从0开始的。支持负偏移量。
索引
>>> T[0],T[-2]
('d', 'g')
分片
T[开始:结束] 包含开始的位置,不包含结束的位置
>>> T[1:3],T[1:],T[:3],T[-1],T[0:-1]
('ie', 'iege', 'die', 'e', 'dieg')
>>> T[:]
'diege‘
简单总结:
*索引(S[i])获取特定偏移的元素。
——第一个元素偏移为0
——(S[0])获取第一个元素。
——负偏移索引意味着从最后或右边反向进行计数
——(S[-2])获取倒数第二个元素(就像S[len(s)-2]一样
*分片[S[i:j]提取对应的部分作为一个序列
——右边界不包含在内
——分片的边界默认为0和序列的长度,如果没有给出的话S[:]
——(S[1:3])获取了从偏移为1,直到但不包括偏移为3的元素
——(S[1:])获取从偏移为1到末尾之间的元素
——(S[:3])获取从偏移为0直到但不包括偏移为3的元素
——(S[:-1])获取从偏移为0直到但不包括最后一个元素之间的元素
——(S[:])获取从偏移为0到末尾之间的元素,这有效地实现了顶层S拷贝
拷贝了一个相同值,但是是不同内存区域的对象。对象字符串这样不可变的对象不是很有用,但是对于可以实地修改的对象来说很有用。
比如列表。
3、扩展分片:第三个限制值 步进
完整形式:X[I:J:K]:这标识索引X对象的元素,从偏移为I直到J-1,每隔K元素索引一次。第三个限制值,K,默认为1
实例
>>> S='abcdefghijk'
>>> S[1:10]
'bcdefghij'
>>> S[1:10:2]
'bdfhj
也可以使用负数作为步进。
分片表达式
>>> "hello"[::-1]
'olleh'
通过负数不尽,两个边界的意义实际上进行了反转。
import sys
print sys.argv
# python echo.py -a -b -c
['echo.py', '-a', '-b', '-c']
echo.py内容
import sys
print sys.argv[1:]
# python echo.py -a -b -c
['-a', '-b', '-c']
4、字符串转换工具
Pyhon的设计座右铭之一是拒绝猜测的诱惑
Python中不能够让数字和字符串相加,甚至即时字符串看起来像是数字也不可以。
>>> '55'+1
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: cannot concatenate 'str' and 'int' objects
+可以加法运算也可以进行合并操作,这种会话选择会模棱两可。要避免这样的语法。
解决脚本文件和用户界面得到一个作为字符串出现的数字该这么办?
解决办法 使用转换工具预先处理,把字符串当做数字,或者把数字当做字符串。
数字转换为字符串的方法
>>> str(55)
'55'
>>> '55'
'55
>>> T=repr(55)
>>> type(T)
<type 'str'>
字符串转换为数字
>>> int('66')
66
>>> D=int('66')
>>> type(D)
<type 'int'>
这些操作为重新创建对象。
>>> S='55'
>>> x=1
>>> int(S)+x
56
类似的内置函数可以把浮点数转换为字符串,或者把字符串转换为浮点数
>>> str(3.1415),float("1.5")
('3.1415', 1.5)
>>> text='1.234E-10'
>>> float(text)
1.234e-10
内置eval函数,它将会运行一个包含了python表达式代码的字符串,并能够将一个字符串转换为任意类型对象。
函数int和float只能对数字进行转换。
**字符串代码转换**
同样是转换,单个的字符也可以通过将其传给内置的ord函数转换为其对应的ASCII码--这个函数实际上返回的是这个字符在内存中对应字符的二进制。
内置chr函数则将二进制转为字符。
>>> ord('t')
116
>>> chr(116)
't'
5、修改字符串
不可变序列,不能实地修改一个字符串(如给一个索引进行赋值)
如果需要改变一个字符串,需要利用合并,分片等工具来建立并赋值给一个新的字符串,倘若必要的话,之后将这个结果赋值给字符串最初的变量名。
>>> S='diege'
>>> S='My name is'+ S
>>> S
'My name isdiege'
这样的修改原来的对象没有改变,只是创建了新的字符串对象,用原来的变量名连接到新的对象而已。
>>> T='diege'
>>> S=T[:3] + 'bad'+T[:-1]
>>> S
'diebaddieg’
每一次修改字符串就是生产一个新的字符串对象。
三、字符串格式化
格式化字符串的方法:
1)、在%操作符的左侧放置一个需要进行格式化的【字符串】,这个字符串带有一个或者多个嵌入的转换目标,都以%开头(如%d)
2)、在%操作符右侧放置一个对象(或多个,在括号内),这些对象将会插入到左侧想让Python进行格式化字符串的(或多个)转换目标的位置上去。
>>> name='diege'
>>> "My name is:%s" % name
'My name is:diege'
>>> name='diege'
>>> age=18
>>> "My name is:%s my age is %d" % (name,age)
'My name is:diege my age is 18'
>>> "%d %s %d you" % (1,'diege',4)
'1 diege 4 you
>>> "%s--%s--%s" % (42,3.1415,[1,2,4])
'42--3.1415--[1, 2, 4]
这个例子插入三个值,一个整数,一个浮点数,一个表对象,但是注意到所有的左侧目标都是%s,这就表示要把他们转换为字符串。由于任何对象都可以转换为字符串(打印时所使用的),每一个与%s一同参与操作的对象类型都可以转换代码。正因如此,除非你要做特殊的格式化,一般你只需要记得用%s这个代码来格式化表达式。
格式化总会是返回新的字符串作为结果而不是对左侧的字符串进行修改。由于字符串是不可变的,所以只能这样操作。如果需要,可以分配一个变量名来保存结果。
1、更高级的字符串格式化
Python字符串格式化支持C语言中所有常规的printf格式的代码(但是并不像printf那样显示结果,而是返回结果)。表中的一些格式化代码为同一类型的格式化提供了不同的选择。
代码 意义
%s 字符串(或任何对象)
%r s,但是用repr,而不是str
%c 字符
%d 十进制(整数)
%i 整数
%u 无号(整数)
%o 八进制整数
%x 十六进制整数
%X x,但打印大写
%e 浮点指数
%E 浮点,但打印大写
%f 浮点十进制
%g 浮点e或f
%G 浮点E或f
%% 常量%
表达式左侧的转换目标支持多种转换操作。这些操作自有一套相当严谨的语法。转换目标的通用结构看上去是这样的:
$[(name)][flags][width][.precision]code
引用字典的索引键,填充的标志,宽度
负号 左对齐
正号 右对齐
>>> x=1234
>>> res="test:...%d...%-6d...%06d" % (x,x,x)
>>> res
'test:...1234...1234 ...001234'
res="test:...%d...%6d...%-06d" % (x,x,x)
%6d 右对齐 宽度6 不够空格补全
%-06d 左对齐 宽度6 不够0补全
2、基于字典的字符串格式化
字符串的格式化同时也允许左边的转换目标来引用右边字典中的键来提取对应的值。
>>> "%(n)d %(x)s" % {"n":1,"x":'diege'}
'1 diege'
(n) (x) 引用了右边字典中的键,并提取他们相应的值。生成类似HTML或者XML的程序往往利用这一技术。
>>> reply="""
... Greetings.
... Hello %(name)s!
... Your age is %(age)s
... """
>>> values={'name':'diege','age':18}
>>> print reply % values
Greetings.
Hello diege!
Your age is 18
这样的小技巧也常与内置函数vars联起来一同使用,这个函数返回的字典包含了所有在本函数调用时存在的变量。
>>> name='diege'
>>> age='18'
>>> vars()
{'S': 'diebaddieg', 'res': 'test:...1234... 1234... 1234', 'D': 66, '__builtins__': <module '__builtin__' (built-in)>, 'text': '1.234E-10', 'age': '18',
'myname': 'diege', '__package__': None, 's': 'e', 'values': {'age': 18, 'name': 'diege'}, 'T': 'diege', 'x': 1234, 'reply': '\nGreetings.\nHello %(name)s!\nYour
age is %(age)s\n', '__name__': '__main__', '__doc__': None, 'name': 'diege'}
>>> "My name is %(name)s age is %(age)s" % vars()
'My name is diege age is 18'
四、字符串方法
除表达式运算符外,字符串还提供了一系列的方法去实现更复杂的文本处理任务。方法就是与特定的对象相关联在一些的函数。从技术的角度讲,他们附属于对象的属性,而这些属性不过是些可调用函数罢了。在Python中,对不同的对象类型有不同的方法。字符串方法仅限于字符串对象。函数也就是代码包,方法调用同时进行了两次操作(一次获取属性和一次函数调用)
属性读取
具有object.attribute格式的表达式可以理解为“读取object对象的属性attribute的值".
函数调用表达式
具有函数(参数)格式的表达式意味着”调用函数代码,传递零或者更多逗号隔开的参数对象,最后返回函数的返回值”。
将两者合并可以让我们调用一个对象方法。方法调用表达式对象,方法(参数)从左至右运行,也就是说Python首先读取对象方法,然后调用它,传递参数。如果一个方法计算出一个结果,它将会作为整个方法调用表达式的结果被返回。
绝大多数对象都可调用的方法。而且所有对象都可以通过同样的方法调用的语法来访问。为了调用对象的方法,必须确保这个对象是存在的。
1、字符串方法实例:修改字符串
字符串方法
>>> dir(S)
['__add__', '__class__', '__contains__', '__delattr__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__',
'__getslice__', '__gt__', '__hash__', '__init__', '__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__',
'__repr__', '__rmod__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '_formatter_field_name_split', '_formatter_parser',
'capitalize', 'center', 'count', 'decode', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'index', 'isalnum', 'isalpha', 'isdigit', 'islower', 'isspace',
'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'partition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split',
'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill']
可以通过help()函数查看方法如何使用
>>> help(S.isupper())
1)替换
替换第3,4个字符
>>> S='namediege'
>>> S=S[:3] +'XX'+S[5:]
>>> S
'namXXiege'
仅仅替换一个子字符串的话,可以使用replace方法实现
>>> S='aabbccdd'
>>> S=S.replace('bb','gg')
>>> S
'aaggccdd'
replace 第一个参数是原始字符串(任意长度),第二个参数替换原始字符串的字符串(任意长度)
2)查找
find方法返回在子字符串出现处的偏移(默认从前向后开始搜索)或者未找到时返回-1.
3)打散 list()
list方法
>>> S='diege'
>>> list(S)
['d', 'i', 'e', 'g', 'e']
会打散成一个列表
4)合成jion()方法
>>> S='diege'
>>> list(S)
['d', 'i', 'e', 'g', 'e']
>>> T=list(S)
>>> T
['d', 'i', 'e', 'g', 'e']
>>> T[0]='P'
>>> T[3]='G'
>>> T
['P', 'i', 'e', 'G', 'e']
>>> S=''.join(T) #使用空字符串分割把字符列表转换为字符串
>>> S
'PieGe'
>>> Y='|'.join(T)
>>> Y
'P|i|e|G|e' #使用|分割把字符串列表转换为字符串
>>> 'X'.join(['eggs','toast','moa'])
'eggsXtoastXmo
2、字符串方法实例:文本解析
1)使用分片做文本解析
>>> line="aaa bbb ccc"
>>> cols1=line[0:3]
>>> cols2=line[8:]
>>> cols1
'aaa'
>>> cols2
'ccc。
在组数据出现在固定偏移处,因此有可能通过分片从原始字符串分出来。这一技术可以被认为是解析,只要所需的数据组键有固定的偏移。
2)split方法提取组件
当所需数据没有固定的偏移时,使用split方法提取组件.在字符串中,数据出现在任意位置,这种方法都能够工作。
>>> line='aaa bbb ccc'
>>> cols=line.split()
>>> cols
['aaa', 'bbb', 'ccc']
字符串的split方法用分割符将一个字符串分割为一个子字符串的列表。默认的分隔符为空格--这个字符串被一个或多个空格,制表符或者换行符分成多个组,之后我们得到了一个最终子字符串的列表。
>>> names='diege,kelly,lily'
>>> names.split()
['diege,kelly,lily']
>>> names.split(',')
['diege', 'kelly', 'lily']
3、实际应用中的其他常见的字符串方法
其他的字符串方法都有更专注的角色
清除每行末尾的空白,执行大小写转换,以及检测末尾的子字符串.
>>> line='The python is running!\n'
>>> line.rstrip()
'The python is running!
>>> line.upper()
'THE PYTHON IS RUNNING!\n
>>> line.isalpha()
False
>>> line.endswith('ing!\n')
True
>>> line.find('ing')!=-1
True
注意没有字符串支持模式---对于基于模式的文本处理,必须使用Python的re标准库模块。字符串方法有时与re模块的工具比较起来,有运行速度方面的优势
4、最初的字符串模块
最初的字符串模块为string模块,其中包含的函数大约相当于目前的字符串方法集。而今应该只使用字符串方法,而不是最初的string模块
五、通常意义下的类型分类
1、同样分类的类型共享其操作集合
字符串是不可改变的序列,不能在原处改变,是位置相关排序好的集合。Python中对所有序列型数据类型-都支持序列的操作--合并,索引,迭代。类似于序列操作,在Ptyhon中有三个类型(以及操作)的分类、
*数字
支持加法,乘法等
*序列
支持索引,分片和合并等
*映射
支持通过键的索引等。
例如对于任意序列对象X和Y:
X+Y 将会创建一个包含两个操作对象内容的新的序列对象
X*N 将会包含操作对象X内容的N份拷贝的新的序列对象
换句话说,这些操作工作起来对于任意一种序列对象都一样,包括字符串,列表,元组以及用户定义的对象类型。对象的类型将会告诉Python去执行什么样的任务。
2、可变类型能够在原处修改
不可变的分类是需要特别注意的约束。如果一个对象是不可变的,那么就不能再原处修改它的值。替代方法,必须运行代码来创建一个新的对象来包含这个新的值。不可变类型有某种完整性,保证这个对象不会被程序的其他部分改变。
可变的类型能在原处修改,可以根据需要修改原数据。
关于方法和表达式小总结:
方法是类型特定的,不具有通用性
表达式是通用的,可以用于多种类型。比如切片在支持序列的对象类型:字符串,列表,元组中通用。