Python中常用操作字符串的函数与方法总结
例如这样一个字符串Python,它就是几个字符:P,y,t,h,o,n,排列起来。这种排列是非常严格的,不仅仅是字符本身,而且还有顺序,换言之,如果某个字符换了,就编程一个新字符串了;如果这些字符顺序发生变化了,也成为了一个新字符串。
在Python中,把像字符串这样的对象类型(后面还会冒出来类似的其它有这种特点的对象类型,比如列表),统称为序列。顾名思义,序列就是“有序排列”。
比如水泊梁山的108个好汉(里面分明也有女的,难道女汉子是从这里来的吗?),就是一个“有序排列”的序列。从老大宋江一直排到第108位金毛犬段景住。在这个序列中,每个人有编号,编号和每个人一一对应。1号是宋江,2号是卢俊义。反过来,通过每个人的姓名,也能找出他对应的编号。武松是多少号?14号。李逵呢?22号。
在Python中,给这些编号取了一个文雅的名字,叫做索引(别的编程语言也这么称呼,不是Python独有的。)。
索引和切片
前面用梁山好汉的为例说明了索引。再看Python中的例子:
>>>lang="studyPython" >>>lang[0] 's' >>>lang[1] 't'
有一个字符串,通过赋值语句赋给了变量lang。如果要得到这个字符串的第一个单词s,可以用lang[0]。当然,如果你不愿意通过赋值语句,让变量lang来指向那个字符串,也可以这样做:
>>>"studyPython"[0] 's'
效果是一样的。因为lang是标签,就指向了"studyPython"字符串。当让Python执行lang[0]的时候,就是要转到那个字符串对象,如同上面的操作一样。只不过,如果不用lang这么一个变量,后面如果再写,就费笔墨了,要每次都把那个字符串写全了。为了省事,还是复制给一个变量吧。变量就是字符串的代表了。
字符串这个序列的排序方法跟梁山好汉有点不同,第一个不是用数字1表示,而是用数字0表示。不仅仅Python,其它很多语言都是从0开始排序的。为什么这样做呢?这就是规定。当然,这个规定是有一定优势的。此处不展开,有兴趣的网上去google一下,有专门对此进行解释的文章。
上面的表格中,将这个字符串从第一个到最后一个进行了排序,特别注意,两个单词中间的那个空格,也占用了一个位置。
通过索引能够找到该索引所对应的字符,那么反过来,能不能通过字符,找到其在字符串中的索引值呢?怎么找?
>>>lang.index("p") 6
就这样,是不是已经能够和梁山好汉的例子对上号了?只不过区别在于第一个的索引值是0。
如果某一天,宋大哥站在大石头上,向着各位弟兄大喊:“兄弟们,都排好队。”等兄弟们排好之后,宋江说:“现在给各位没有老婆的兄弟分配女朋友,我这里已经有了名单,我念叨的兄弟站出来。不过我是按照序号来念的。第29号到第34号先出列,到旁边房子等候分配女朋友。”
在前面的例子中lang[1]能够得到原来字符串的第二个字符t,就相当于从原来字符串中把这个“切”出来了。不过,我们这么“切”却不影响原来字符串的完整性,当然可以理解为将那个字符t赋值一份拿出来了。
那么宋江大哥没有一个一个“切”,而是一下将几个兄弟叫出来。在Python中也能做类似事情。
>>>lang 'studyPython'#在前面“切”了若干的字符之后,再看一下该字符串,还是完整的。 >>>lang[2:9] 'udypyt'
通过lang[2:9]要得到部分(不是一个)字符,从返回的结果中可以看出,我们得到的是序号分别对应着2,3,4,5,6,7,8(跟上面的表格对应一下)字符(包括那个空格)。也就是,这种获得部分字符的方法中,能够得到开始需要的以及最后一个序号之前的所对应的字符。有点拗口,自己对照上面的表格数一数就知道了。简单说就是包括开头,不包括结尾。
上述,不管是得到一个还是多个,通过索引得到字符的过程,称之为切片。
切片是一个很有意思的东西。可以“切”出不少花样呢?
>>>lang 'studyPython' >>>b=lang[1:]#得到从1号到最末尾的字符,这时最后那个需要不用写 >>>b 'tudyPython' >>>c=lang[:]#得到所有字符 >>>c 'studyPython' >>>d=lang[:10]#得到从第一个到10号之前的字符 >>>d 'studypyth'
在获取切片的时候,如果分号的前面或者后面的序号不写,就表示是到最末(后面的不写)或第一个(前面的不写)
lang[:10]的效果和lang[0:10]是一样的。
>>>e=lang[0:10] >>>e 'studypyth'
那么,lang[1:]和lang[1:11]效果一样吗?请思考后作答。
>>>lang[1:11] 'tudypytho' >>>lang[1:] 'tudypython'
果然不一样,你思考对了吗?原因就是前述所说的,如果分号后面有数字,所得到的切片,不包含该数字所对应的序号(前包括,后不包括)。那么,是不是可以这样呢?lang[1:12],不包括12号(事实没有12号),是不是可以得到1到11号对应的字符呢?
>>>lang[1:12] 'tudypython' >>>lang[1:13] 'tudypython'
果然是。并且不仅仅后面写12,写13,也能得到同样的结果。但是,我这个特别要提醒,这种获得切片的做法在编程实践中是不提倡的。特别是如果后面要用到循环的时候,这样做或许在什么时候遇到麻烦。
如果在切片的时候,冒号左右都不写数字,就是前面所操作的c=lang[:],其结果是变量c的值与原字符串一样,也就是“复制”了一份。注意,这里的“复制”我打上了引号,意思是如同复制,是不是真的复制呢?可以用下面的方式检验一下
>>>id(c) 3071934536L >>>id(lang) 3071934536L
id()的作用就是查看该对象在内存地址(就是在内存中的位置编号)。从上面可以看出,两个的内存地址一样,说明c和lang两个变量指向的是同一个对象。用c=lang[:]的方式,并没有生成一个新的字符串,而是将变量c这个标签也贴在了原来那个字符串上了。
>>>lang="studypython" >>>c=lang
如果这样操作,变量c和lang是不是指向同一个对象呢?或者两者所指向的对象内存地址如何呢?看官可以自行查看。
字符串基本操作
字符串是一种序列,所有序列都有如下基本操作:
- len():求序列长度
- :连接2个序列
- :重复序列元素
- in:判断元素是否存在于序列中
- max():返回最大值
- min():返回最小值
- cmp(str1,str2):比较2个序列值是否相同
通过下面的例子,将这几个基本操作在字符串上的使用演示一下:
“+”连接字符串
>>>str1+str2 'abcdabcde' >>>str1+"-->"+str2 'abcd-->abcde'
这其实就是拼接,不过在这里,看官应该有一个更大的观念,我们现在只是学了字符串这一种序列,后面还会遇到列表、元组两种序列,都能够如此实现拼接。
in
>>>"a"instr1 True >>>"de"instr1 False >>>"de"instr2 True
in用来判断某个字符串是不是在另外一个字符串内,或者说判断某个字符串内是否包含某个字符串,如果包含,就返回True,否则返回False。
最值
>>>max(str1) 'd' >>>max(str2) 'e' >>>min(str1) 'a'
一个字符串中,每个字符在计算机内都是有编码的,也就是对应着一个数字,min()和max()就是根据这个数字里获得最小值和最大值,然后对应出相应的字符。关于这种编号是多少,看官可以google有关字符编码,或者ASCII编码什么的,很容易查到。
比较
>>>cmp(str1,str2) -1
将两个字符串进行比较,也是首先将字符串中的符号转化为对一个的数字,然后比较。如果返回的数值小于零,说明第一个小于第二个,等于0,则两个相等,大于0,第一个大于第二个。为了能够明白其所以然,进入下面的分析。
>>>ord('a') 97 >>>ord('b') 98 >>>ord('') 32
ord()是一个内建函数,能够返回某个字符(注意,是一个字符,不是多个字符组成的串)所对一个的ASCII值(是十进制的),字符a在ASCII中的值是97,空格在ASCII中也有值,是32。顺便说明,反过来,根据整数值得到相应字符,可以使用chr():
>>>chr(97) 'a' >>>chr(98) 'b'
于是,就得到如下比较结果了:
>>>cmp("a","b")#a-->97,b-->98,97小于98,所以a小于b -1 >>>cmp("abc","aaa") 1 >>>cmp("a","a") 0
看看下面的比较,是怎么进行的呢?
>>>cmp("ad","c") -1
在字符串的比较中,是两个字符串的第一个字符先比较,如果相等,就比较下一个,如果不相等,就返回结果。直到最后,如果还相等,就返回0。位数不够时,按照没有处理(注意,没有不是0,0在ASCII中对应的是NUL),位数多的那个天然大了。ad中的a先和后面的c进行比较,显然a小于c,于是就返回结果-1。如果进行下面的比较,是最容易让人迷茫的。看官能不能根据刚才阐述的比较远离理解呢?
>>>cmp("123","23") -1 >>>cmp(123,23)#也可以比较整数,这时候就是整数的直接比较了。 1 “*”
字符串中的“乘法”,这个乘法,就是重复那个字符串的含义。在某些时候很好用的。比如我要打印一个华丽的分割线:
>>>str1*3 'abcdabcdabcd' >>>print"-"*20#不用输入很多个`-` -------------------- len()
要知道一个字符串有多少个字符,一种方法是从头开始,盯着屏幕数一数。哦,这不是计算机在干活,是键客在干活。
键客,不是剑客。剑客是以剑为武器的侠客;而键客是以键盘为武器的侠客。当然,还有贱客,那是贱人的最高境界,贱到大侠的程度,比如岳不群之流。
键客这样来数字符串长度:
>>>a="hello" >>>len(a) 5
使用的是一个函数len(object)。得到的结果就是该字符串长度。
>>>m=len(a)#把结果返回后赋值给一个变量 >>>m 5 >>>type(m)#这个返回值(变量)是一个整数型 <type'int'>
字符串格式化输出
什么是格式化?在维基百科中有专门的词条,这么说的:
格式化是指对磁盘或磁盘中的分区(partition)进行初始化的一种操作,这种操作通常会导致现有的磁盘或分区中所有的文件被清除。
不知道你是否知道这种“格式化”。显然,此格式化非我们这里所说的,我们说的是字符串的格式化,或者说成“格式化字符串”,都可以,表示的意思就是:
格式化字符串,是C、C++等程序设计语言printf类函数中用于指定输出参数的格式与相对位置的字符串参数。其中的转换说明(conversionspecification)用于把随后对应的0个或多个函数参数转换为相应的格式输出;格式化字符串中转换说明以外的其它字符原样输出。
这也是来自维基百科的定义。在这个定义中,是用C语言作为例子,并且用了其输出函数来说明。在Python中,也有同样的操作和类似的函数print,此前我们已经了解一二了。
如果将那个定义说的通俗一些,字符串格式化化,就是要先制定一个模板,在这个模板中某个或者某几个地方留出空位来,然后在那些空位填上字符串。那么,那些空位,需要用一个符号来表示,这个符号通常被叫做占位符(仅仅是占据着那个位置,并不是输出的内容)。
>>>"Ilike%s" 'Ilike%s'
在这个字符串中,有一个符号:%s,就是一个占位符,这个占位符可以被其它的字符串代替。比如:
>>>"Ilike%s"%"python" 'Ilikepython' >>>"Ilike%s"%"Pascal" 'IlikePascal'
这是较为常用的一种字符串输出方式。
另外,不同的占位符,会表示那个位置应该被不同类型的对象填充。下面列出许多,供参考。不过,不用记忆,常用的只有%s和%d,或者再加上%f,其它的如果需要了,到这里来查即可。
看例子:
>>>a="%dyears"%15 >>>printa 15years
当然,还可以在一个字符串中设置多个占位符,就像下面一样
>>>print"Suzhouismorethan%dyears.%slivesinhere."%(2500,"qiwsir") Suzhouismorethan2500years.qiwsirlivesinhere.
对于浮点数字的打印输出,还可以限定输出的小数位数和其它样式。
>>>print"Today'stemperatureis%.2f"%12.235 Today'stemperatureis12.23 >>>print"Today'stemperatureis%+.2f"%12.235 Today'stemperatureis+12.23
注意,上面的例子中,没有实现四舍五入的操作。只是截取。
常用的字符串方法
字符串的方法很多。可以通过dir来查看:
>>>dir(str) ['__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(str.isalpha)
Helponmethod_descriptor: isalpha(...) S.isalpha()->bool ReturnTrueifallcharactersinSarealphabetic andthereisatleastonecharacterinS,Falseotherwise.
按照这里的说明,就可以在交互模式下进行实验。
>>>"python".isalpha()#字符串全是字母,应该返回True True >>>"2python".isalpha()#字符串含非字母,返回False False
split
这个函数的作用是将字符串根据某个分割符进行分割。
>>>a="ILOVEPYTHON" >>>a.split("") ['I','LOVE','PYTHON']
这是用空格作为分割,得到了一个名字叫做列表(list)的返回值,关于列表的内容,后续会介绍。还能用别的分隔吗?
>>>b="www.itdiffer.com" >>>b.split(".") ['www','itdiffer','com']
去掉字符串两头的空格
这个功能,在让用户输入一些信息的时候非常有用。有的朋友喜欢输入结束的时候敲击空格,比如让他输入自己的名字,输完了,他来个空格。有的则喜欢先加一个空格,总做的输入的第一个字前面应该空两个格。
这些空格是没用的。Python考虑到有不少人可能有这个习惯,因此就帮助程序员把这些空格去掉。
方法是:
- S.strip()去掉字符串的左右空格
- S.lstrip()去掉字符串的左边空格
- S.rstrip()去掉字符串的右边空格
- 例如:
>>>b="hello"#两边有空格 >>>b.strip() 'hello' >>>b 'hello'
特别注意,原来的值没有变化,而是新返回了一个结果。
>>>b.lstrip()#去掉左边的空格 'hello' >>>b.rstrip()#去掉右边的空格 'hello'
字符大小写的转换
对于英文,有时候要用到大小写转换。最有名驼峰命名,里面就有一些大写和小写的参合。如果有兴趣,可以来这里看自动将字符串转化为驼峰命名形式的方法。
在Python中有下面一堆内建函数,用来实现各种类型的大小写转化
- S.upper()#S中的字母大写
- S.lower()#S中的字母小写
- S.capitalize()#首字母大写
- S.isupper()#S中的字母是否全是大写
- S.islower()#S中的字母是否全是小写
- S.istitle()
- 看例子:
>>>a="qiwsir,Python" >>>a.upper()#将小写字母完全变成大写字母 'QIWSIR,PYTHON' >>>a#原数据对象并没有改变 'qiwsir,Python' >>>b=a.upper() >>>b 'QIWSIR,PYTHON' >>>c=b.lower()#将所有的小写字母变成大写字母 >>>c 'qiwsir,Python' >>>a 'qiwsir,Python' >>>a.capitalize()#把字符串的第一个字母变成大写 'Qiwsir,Python' >>>a#原数据对象没有改变 'qiwsir,Python' >>>b=a.capitalize()#新建立了一个 >>>b 'Qiwsir,Python' >>>a="qiwsir,github"#这里的问题就是网友白羽毛指出的,非常感谢他。 >>>a.istitle() False >>>a="QIWSIR"#当全是大写的时候,返回False >>>a.istitle() False >>>a="qIWSIR" >>>a.istitle() False >>>a="Qiwsir,github"#如果这样,也返回False >>>a.istitle() False >>>a="Qiwsir"#这样是True >>>a.istitle() True >>>a='Qiwsir,Github'#这样也是True >>>a.istitle() True >>>a="Qiwsir" >>>a.isupper() False >>>a.upper().isupper() True >>>a.islower() False >>>a.lower().islower() True
再探究一下,可以这么做:
>>>a="ThisisaBook" >>>a.istitle() False >>>b=a.title()#这样就把所有单词的第一个字母转化为大写 >>>b 'ThisIsABook' >>>b.istitle()#判断每个单词的第一个字母是否为大写 True
join拼接字符串
用“+”能够拼接字符串,但不是什么情况下都能够如愿的。比如,将列表(关于列表,后续详细说,它是另外一种类型)中的每个字符(串)元素拼接成一个字符串,并且用某个符号连接,如果用“+”,就比较麻烦了(是能够实现的,麻烦)。
用字符串的join就比较容易实现。
>>>b 'www.itdiffer.com' >>>c=b.split(".") >>>c ['www','itdiffer','com'] >>>".".join(c) 'www.itdiffer.com' >>>"*".join(c) 'www*itdiffer*com'
这种拼接,是不是简单呢?