首页 > 代码库 > 第3章 字符串

第3章 字符串

3.1 基本字符串操作

  所有标准的序列操作(索引、分片、乘法、判断成员资格、求长度、取最大值和最小值)对字符串同样适用。字符串都是不可变的。因此,类似以下的分片赋值是不合法的:

>>> website = "http://www.python.org"
>>> website[-3:] = "com"
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: str object does not support item assignment

3.2 字符串格式化:精简版

  字符串格式化适用字符串格式化即百分号(%)来实现。%也可以用作模运算(求余)操作符。

技术分享
>>> format = "Hello,%s.%s enough for ya?"
>>> values = ("World","Hot")
>>> print(format % values)
Hello,World.Hot enough for ya?
View Code

  希望格式化的值可以使用一个值,如一个字符串或者数字,也可以使用多个值的元组。如果使用列表或者其他序列代替元组,那么序列就会被解释为一个值。只有元组和字典可以格式化一个以上的值。

  格式化字符串的%s部分称为转换说明符(conversion specifier),它们标记了需要插入转换值的位置。s表示值会被格式化字符串---如果不是字符串,则会用str将其转换为字符串。如果要在格式化字符串里面包括百分号,那么必须使用%%,这样Python就不会将百分号误认为是转换说明符了。

  如果要格式化实数(浮点数),可以使用f说明符类型,同时提供所需要的精度:一个句点再加上希望保留的小数位数。

>>> format = "Pi with three decimals: %.3f"
>>> from math import pi
>>> print(format % pi)
Pi with three decimals: 3.142

3.3 字符串格式化:完整版

  格式化操作符的右操作数可以是任何东西,如果是元组或者映射类型(如字典),那么字符串格式化将会有所不同。

  如果右操作数是元组的话,则其中的每一个元素都会被单独格式化,每个值都需要一个对应的转换说明符。需要转换的元组作为转换表达式的一部分存在,必须使用圆括号括起来。

>>> "%s plus %s equal %s" % (1,1,2)
1 plus 1 equal 2
>>> "%s plus %s equal %s" % 1,1,2
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: not enough arguments for format string

  基本的转换说明符(完整的则包括映射键的说明符)包括以下部分。注意,这些项的顺序是至关重要的。

  (1)%字符:转换说明符的开始

  (2)转换标志(可选):- 表示左对齐;+ 表示在转换值之前要加上正负号;"" (空白字符)表示正数之前保留空格;0 表示转换值若位数不够则用0填充。

  (3)最小字段宽度(可选):转换后的字符串至少应该具有该值指定的宽度。如果是*,则宽度会从值元组中读出。

  (4)点(.)后跟精度值(可选):如果转换的是实数,精度值就表示出现在小数点后面的位数。如果转换的是字符串,那么该数字就表示最大字段宽度。如果是*,那么精度将会从元组中读出。

  (5)转换类型:参见表3-1

                    技术分享

3.3.1 简单转换

  简单的转换只需要写出转换类型:

>>> "Price of eggs: $%d" % 42
Price of eggs: $42
>>> "Price of eggs: %x" % 42
Price of eggs: 2a
>>> from math import pi
>>> "Pi: %f..." % pi
Pi: 3.141593...
>>> "Very inexact estimate of pi: %i" % pi
Very inexact estimate of pi: 3

3.3.2 字符宽度和精度

  转换说明符可以包括字符宽度和精度。字段宽度是转换后的值所保留的最小字符个数,精度(对于数字转换来说)则是结果中应该包含的小数位数,或者(对于字符串转换来说)是转换后的值所能包含的最大字符个数。这两个参数都是整数(首先是字段宽度,然后是精度),通过点号(.)分隔,但如果只给出了精度,就必须包含点号:

>>> "%10f" % pi      #字段宽10
  3.141593
>>> "%10.2f" % pi   #字段宽10,精度2
      3.14
>>> "%.2f" % pi       #精度2
3.14
>>> "%.5s" % "Guido van Rossum"
Guido

  可以使用*(星号)作为字段宽度或者精度(或者两者都使用),此时数值会从元组参数中读出:

>>> "%.*s" % (5,"Guido van Rossum")
Guido

3.3.3 符号、对齐和0填充

  在字段宽度和精度值之前还可以放置一个“标表”,该标表可以是零、加号、减号或空格。零表示数字将会用0进行填充。

>>> "%010.2f" % pi
0000003.14

  注意,在010中开头的那个0不是字段宽度说明符为八进制,它只是个普通的Python数值。当使用010作为字段宽度说明符的时候,表示字段宽度为10,并且用0进行填充空位。

  减号(-)用来左对齐数值:右侧多出了额外的空格

>>> "%-10.2f" % pi
3.14      

  空白(“”)意味着正数前加上空格。这在需要对齐正负数时会很有用:

>>> print(("% 5d" % 10) + "\n" + ("% 5d" % -10))
   10
  -10

  加号(+),它表示不管是正数还是负数都标示出符号

>>> print(("%+5d" % 10) + "\n" + ("%+5d" % -10))
  +10
  -10

3.4 字符串方法

3.4.1 find

  find方法可以在一个较长的字符串中查找子字符串。它返回子串所在位置的最左端索引。如没有找到则返回-1:

>>> "With a moo-moo here,and a moo-moo here there".find("moo")
7
>>> title = "Monty Python‘s Flying Circus"
>>> title.find("Monty")
0
>>> title.find("Python")
6
>>> title.find("Zirquss")
-1

  find方法还可以接受可选的起始点和结束点参数:注意,由起始和终止值指定的返回包含第一个索引,但不包含第二个索引。这是Python的惯例。

>>> subject = "$$$ Get rich now!!! $$$"
>>> subject.find("$$$")
0
>>> subject.find("$$$",1) #只提供起始点
20
>>> subject.find("!!!")
16
>>> subject.find("!!!",0,16)  #提供起始点和结束点,但不包含结束点
-1

3.4.2 join

  join方法是非常重要的字符串方法,它是split方法的逆方法,用来在队列中添加元素:

>>> seq = [1,2,3,4,5]
>>> sep = ("+")
>>> sep.join(seq) #连接数字列表
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: sequence item 0: expected str instance, int found
>>> seq = ["1","2","3","4","5"]
>>> sep.join(seq)  #连接字符串列表
1+2+3+4+5
>>> dirs = "","usr","bin","env"
>>> "/".join(dirs)  #UNIX下的分隔符
/usr/bin/env
>>> print("C:" + "\\".join(dirs)) #转义Windows分隔符号“\”
C:\usr\bin\env

  需要添加的队列元素都必须是字符串,最后两个例子中使用了目录的列表,根据操作系统的约定,使用了不同的分隔符号。

3.4.3 split

  用来将字符串分割成序列:

>>> "1+2+3+4+5".split("+")
[1, 2, 3, 4, 5]
>>> "/usr/bin/env".split("/")
[‘‘, usr, bin, env]
>>> "Use the default".split()
[Use, the, default]

  如果不提供任何分隔符,程序会把所有空格作为分隔符(空格、制表、换行等)

3.4.4 lower

  lower方法返回字符串的小写字母版。

>>> "Trondherim Hammer Dance".lower()
trondherim hammer dance

  如果想要编写“不区分大小写”的代码的程序,这个方法就会非常有用----代码会忽略大小写状态。例如,在一个列表中查找某用户是否存在:列表包含字符串“gumby”,而用户输入“Gumby”,就找不到了:

if "Gumby" in ["gumby","smith","jones"]:print("Found it!")
...
>>>

  如果存储的是“Gumby”而用户输入“gumby”或“GUMBY”,结果也是一样的。解决方法就是在存储和搜索时把所有名字都转换为小写。代码如下:

>>> name = "Gumby"
>>> names = ["gumby","smith","jones"]
>>> if name.lower() in names:print("Found it!")
...
Found it!
>>>

  和lower方法相关的是title方法,它会将字符串转换为标题----也就是所有的单词的首字母大写,而其他字母小写。但是它使用的单词划分方法可能会得到并不自然的结果:

>>> "that‘s all right".title()
"That‘S All Right"

  string模块的capwords函数:

>>> import string
>>> string.capwords("that‘s all right") #3.x系列str类型内有内置capwords函数
"That‘s All Right"

  如果要得到正确的首字母大小的标题,还是根据自己的风格而定。

3.4.5 replace

  replace方法返回某字符串的所有匹配项均被替换之后得到字符串,相当于文本处理程序中的"查找并替换"功能。

>>> "This is a test".replace("is","eez") #"is"字符串被"eez"替换
Theez eez a test

3.4.6 strip

  strip方法返回去除两侧(不包含内部)空格的字符串:

>>> "     internal whitespace is kept     ".strip()
internal whitespace is kept

  它和lower方法一起使用就可以很方便的对比输入的和存储的值。假设用户在输入名字时无意在名字后面加上了空格:

>>> name = "gumby "  #如何结合lower,假如name = "Gumby ",判断不能写两个方法if name.strip() and name.lower() in names:如何写?赋值给变量?
>>> names = ["gumby","smith","jones"]
>>> if name in names:print("Found it!")
...
>>> if name.strip() in names:print("Found it!")
...
Found it!
>>>

  也可以指定需要去除的字符,将它们列为参数即可。去除两侧的空格、星号和感叹号:

>>> "*** SPAM * for * everyone!!! ***".strip(" *!")
SPAM * for * everyone

3.4.7 translate

  translate方法和replace方法一样,可以替换字符串中的某些部分,但是和前者不同的是,translate方法只处理单字符。它的优势在于可以同时进行多个替换。使用这个方法的方式有很多(比如替换换行符或者其他因平台而异的特殊字符)。下面是一个简单的例子:假设需要将纯正的英文文本转换为带有德国口音的版本。为此需要把字符c替换为k,把s替换为z。

  在使用translate转换之前,需要先完成一张转换表。转换表中是以某字符替换某字符的对应关系。因此导入string模块里面的maketrans函数(2.x系列在string中,3.x已修改为内置,2.x系列string模块和内置的str类型有很多方法是重复的,所以3.x系列时string模块把这些重复的方法都去掉了,只保留一些独有的方法和常量来有区别与str类型)。maketrans函数接受两个参数:两个等长的字符串,表示第一个字符串中的每个字符都用第二个字符串中相同位置的字符替换。代码如下:

>>> from string import maketrans #2.0系列写法
>>> table = s.maketrans("cs","kz") #3.0系列写法 >>> "this is an incredible test".translate(table) thiz iz an inkredible tezt

3.5 小结

  本章介绍了字符串的两种非常重要的使用方式。

  字符串格式化:求模操作符(%)可以用来将其他值转换为包含转换标志的字符串,例如%s。它还能用来对值进行不同方式的格式化,包括左右对齐、设定字符宽度以及精度值,增加符号(正负号)或者左填充数字0等。

  字符串方法:find、join、split、lower、replace、strip和translate等常用的方法。

3.5.1 本章的新函数

  新涉及的函数如表3-2所示。

                    技术分享

 

第3章 字符串