Python中常用操作字符串的函数与方法总结


Posted in Python onFebruary 04, 2016

例如这样一个字符串 Python,它就是几个字符:P,y,t,h,o,n,排列起来。这种排列是非常严格的,不仅仅是字符本身,而且还有顺序,换言之,如果某个字符换了,就编程一个新字符串了;如果这些字符顺序发生变化了,也成为了一个新字符串。

在 Python 中,把像字符串这样的对象类型(后面还会冒出来类似的其它有这种特点的对象类型,比如列表),统称为序列。顾名思义,序列就是“有序排列”。

比如水泊梁山的 108 个好汉(里面分明也有女的,难道女汉子是从这里来的吗?),就是一个“有序排列”的序列。从老大宋江一直排到第 108 位金毛犬段景住。在这个序列中,每个人有编号,编号和每个人一一对应。1 号是宋江,2 号是卢俊义。反过来,通过每个人的姓名,也能找出他对应的编号。武松是多少号?14 号。李逵呢?22 号。

在 Python 中,给这些编号取了一个文雅的名字,叫做索引(别的编程语言也这么称呼,不是 Python 独有的。)。

索引和切片
前面用梁山好汉的为例说明了索引。再看 Python 中的例子:

>>> lang = "study Python"
>>> lang[0]
's'
>>> lang[1]
't'

有一个字符串,通过赋值语句赋给了变量 lang。如果要得到这个字符串的第一个单词 s,可以用 lang[0]。当然,如果你不愿意通过赋值语句,让变量 lang 来指向那个字符串,也可以这样做:

>>> "study Python"[0]
's'

效果是一样的。因为 lang 是标签,就指向了 "study Python" 字符串。当让 Python 执行 lang[0] 的时候,就是要转到那个字符串对象,如同上面的操作一样。只不过,如果不用 lang 这么一个变量,后面如果再写,就费笔墨了,要每次都把那个字符串写全了。为了省事,还是复制给一个变量吧。变量就是字符串的代表了。

字符串这个序列的排序方法跟梁山好汉有点不同,第一个不是用数字1表示,而是用数字 0 表示。不仅仅 Python,其它很多语言都是从 0 开始排序的。为什么这样做呢?这就是规定。当然,这个规定是有一定优势的。此处不展开,有兴趣的网上去 google 一下,有专门对此进行解释的文章。

0 1 2 3 4 5 6 7 8 9 10 11
s t u d y l p y t h o n

上面的表格中,将这个字符串从第一个到最后一个进行了排序,特别注意,两个单词中间的那个空格,也占用了一个位置。

通过索引能够找到该索引所对应的字符,那么反过来,能不能通过字符,找到其在字符串中的索引值呢?怎么找?

>>> lang.index("p")
6

就这样,是不是已经能够和梁山好汉的例子对上号了?只不过区别在于第一个的索引值是 0。

如果某一天,宋大哥站在大石头上,向着各位弟兄大喊:“兄弟们,都排好队。”等兄弟们排好之后,宋江说:“现在给各位没有老婆的兄弟分配女朋友,我这里已经有了名单,我念叨的兄弟站出来。不过我是按照序号来念的。第 29 号到第 34 号先出列,到旁边房子等候分配女朋友。”

在前面的例子中 lang[1] 能够得到原来字符串的第二个字符 t,就相当于从原来字符串中把这个“切”出来了。不过,我们这么“切”却不影响原来字符串的完整性,当然可以理解为将那个字符 t 赋值一份拿出来了。

那么宋江大哥没有一个一个“切”,而是一下将几个兄弟叫出来。在 Python 中也能做类似事情。

>>> lang
'study Python'  #在前面“切”了若干的字符之后,再看一下该字符串,还是完整的。
>>> lang[2:9]
'udy pyt'

通过 lang[2:9]要得到部分(不是一个)字符,从返回的结果中可以看出,我们得到的是序号分别对应着 2,3,4,5,6,7,8(跟上面的表格对应一下)字符(包括那个空格)。也就是,这种获得部分字符的方法中,能够得到开始需要的以及最后一个序号之前的所对应的字符。有点拗口,自己对照上面的表格数一数就知道了。简单说就是包括开头,不包括结尾。

上述,不管是得到一个还是多个,通过索引得到字符的过程,称之为切片。

切片是一个很有意思的东西。可以“切”出不少花样呢?

>>> lang
'study Python'
>>> b = lang[1:]  # 得到从 1 号到最末尾的字符,这时最后那个需要不用写
>>> b
'tudy Python'
>>> c = lang[:]  # 得到所有字符
>>> c
'study Python'
>>> d = lang[:10]  # 得到从第一个到 10 号之前的字符
>>> d
'study pyth'

在获取切片的时候,如果分号的前面或者后面的序号不写,就表示是到最末(后面的不写)或第一个(前面的不写)

lang[:10]的效果和 lang[0:10]是一样的。

>>> e = lang[0:10]
>>> e
'study pyth'

那么,lang[1:]和 lang[1:11]效果一样吗?请思考后作答。

>>> lang[1:11]
'tudy pytho'
>>> lang[1:]
'tudy python'

果然不一样,你思考对了吗?原因就是前述所说的,如果分号后面有数字,所得到的切片,不包含该数字所对应的序号(前包括,后不包括)。那么,是不是可以这样呢?lang[1:12],不包括 12 号(事实没有 12 号),是不是可以得到 1 到 11 号对应的字符呢?

>>> lang[1:12]
'tudy python'
>>> lang[1:13]
'tudy python'

果然是。并且不仅仅后面写 12,写 13,也能得到同样的结果。但是,我这个特别要提醒,这种获得切片的做法在编程实践中是不提倡的。特别是如果后面要用到循环的时候,这样做或许在什么时候遇到麻烦。

如果在切片的时候,冒号左右都不写数字,就是前面所操作的 c = lang[:],其结果是变量 c 的值与原字符串一样,也就是“复制”了一份。注意,这里的“复制”我打上了引号,意思是如同复制,是不是真的复制呢?可以用下面的方式检验一下

>>> id(c)
3071934536L
>>> id(lang)
3071934536L

id()的作用就是查看该对象在内存地址(就是在内存中的位置编号)。从上面可以看出,两个的内存地址一样,说明 c 和 lang 两个变量指向的是同一个对象。用 c=lang[:]的方式,并没有生成一个新的字符串,而是将变量 c 这个标签也贴在了原来那个字符串上了。

>>> lang = "study python"
>>> c = lang

如果这样操作,变量 c 和 lang 是不是指向同一个对象呢?或者两者所指向的对象内存地址如何呢?看官可以自行查看。

字符串基本操作
字符串是一种序列,所有序列都有如下基本操作:

  • len():求序列长度
  • :连接 2 个序列
  • : 重复序列元素
  • in :判断元素是否存在于序列中
  • max() :返回最大值
  • min() :返回最小值
  • cmp(str1,str2) :比较 2 个序列值是否相同

通过下面的例子,将这几个基本操作在字符串上的使用演示一下:

“+”连接字符串

>>> str1 + str2
'abcdabcde'
>>> str1 + "-->" + str2
'abcd-->abcde'

这其实就是拼接,不过在这里,看官应该有一个更大的观念,我们现在只是学了字符串这一种序列,后面还会遇到列表、元组两种序列,都能够如此实现拼接。

in

>>> "a" in str1
True
>>> "de" in str1
False
>>> "de" in str2
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 类函数中用于指定输出参数的格式与相对位置的字符串参数。其中的转换说明(conversion specification)用于把随后对应的 0 个或多个函数参数转换为相应的格式输出;格式化字符串中转换说明以外的其它字符原样输出。
这也是来自维基百科的定义。在这个定义中,是用 C 语言作为例子,并且用了其输出函数来说明。在 Python 中,也有同样的操作和类似的函数 print,此前我们已经了解一二了。

如果将那个定义说的通俗一些,字符串格式化化,就是要先制定一个模板,在这个模板中某个或者某几个地方留出空位来,然后在那些空位填上字符串。那么,那些空位,需要用一个符号来表示,这个符号通常被叫做占位符(仅仅是占据着那个位置,并不是输出的内容)。

>>> "I like %s"
'I like %s'

在这个字符串中,有一个符号:%s,就是一个占位符,这个占位符可以被其它的字符串代替。比如:

>>> "I like %s" % "python"
'I like python'
>>> "I like %s" % "Pascal"
'I like Pascal'

这是较为常用的一种字符串输出方式。

另外,不同的占位符,会表示那个位置应该被不同类型的对象填充。下面列出许多,供参考。不过,不用记忆,常用的只有 %s 和 %d,或者再加上 %f,其它的如果需要了,到这里来查即可。

占位符 说明
%s 字符串(采用 str()的显示)
%r 字符串(采用 repr()的显示)
%c 单个字符
%b 二进制整数
%d 十进制整数
%i 十进制整数
%o 八进制整数
%x 十六进制整数
%e 指数 (基底写为 e)
%E 指数 (基底写为 E)
%f 浮点数
%F 浮点数,与上相同
%g 指数(e) 或浮点数 (根据显示长度)
%G 指数(E)或浮点数 (根据显示长度)

看例子:

>>> a = "%d years" % 15
>>> print a
15 years

当然,还可以在一个字符串中设置多个占位符,就像下面一样

>>> print "Suzhou is more than %d years. %s lives in here." % (2500, "qiwsir")
Suzhou is more than 2500 years. qiwsir lives in here.

对于浮点数字的打印输出,还可以限定输出的小数位数和其它样式。

>>> print "Today's temperature is %.2f" % 12.235
Today's temperature is 12.23
>>> print "Today's temperature is %+.2f" % 12.235
Today's temperature is +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)
Help on method_descriptor:

isalpha(...)
  S.isalpha() -> bool

  Return True if all characters in S are alphabetic
  and there is at least one character in S, False otherwise.

按照这里的说明,就可以在交互模式下进行实验。

>>> "python".isalpha()  # 字符串全是字母,应该返回 True
True
>>> "2python".isalpha()  # 字符串含非字母,返回 False
False

split

这个函数的作用是将字符串根据某个分割符进行分割。

>>> a = "I LOVE PYTHON"
>>> a.split(" ")
['I', 'LOVE', 'PYTHON']

这是用空格作为分割,得到了一个名字叫做列表(list)的返回值,关于列表的内容,后续会介绍。还能用别的分隔吗?

>>> b = "www.itdiffer.com"
>>> b.split(".")
['www', 'itdiffer', 'com']

去掉字符串两头的空格

这个功能,在让用户输入一些信息的时候非常有用。有的朋友喜欢输入结束的时候敲击空格,比如让他输入自己的名字,输完了,他来个空格。有的则喜欢先加一个空格,总做的输入的第一个字前面应该空两个格。

这些空格是没用的。Python 考虑到有不少人可能有这个习惯,因此就帮助程序员把这些空格去掉。

方法是:

  1. S.strip() 去掉字符串的左右空格
  2. S.lstrip() 去掉字符串的左边空格
  3. S.rstrip() 去掉字符串的右边空格
  4. 例如:
>>> 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 = "This is a Book"
>>> a.istitle()
False
>>> b = a.title()   # 这样就把所有单词的第一个字母转化为大写
>>> b
'This Is A Book'
>>> 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'

这种拼接,是不是简单呢?

Python 相关文章推荐
Python中for循环和while循环的基本使用方法
Aug 21 Python
深入浅出分析Python装饰器用法
Jul 28 Python
python操作redis方法总结
Jun 06 Python
Python解决两个整数相除只得到整数部分的实例
Nov 10 Python
Python遍历字典方式就实例详解
Dec 28 Python
tensorflow指定GPU与动态分配GPU memory设置
Feb 03 Python
Pycharm如何运行.py文件的方法步骤
Mar 03 Python
python 链接sqlserver 写接口实例
Mar 11 Python
Python 基于jwt实现认证机制流程解析
Jun 22 Python
详解Python中Pyyaml模块的使用
Oct 08 Python
在Django中使用MQTT的方法
May 10 Python
Python字典和列表性能之间的比较
Jun 07 Python
Python中的字符串类型基本知识学习教程
Feb 04 #Python
Python的math模块中的常用数学函数整理
Feb 04 #Python
详解Python编程中基本的数学计算使用
Feb 04 #Python
Python连接mysql数据库的正确姿势
Feb 03 #Python
Python内建数据结构详解
Feb 03 #Python
Python解析树及树的遍历
Feb 03 #Python
Python实现二叉堆
Feb 03 #Python
You might like
高亮度显示php源代码
2006/10/09 PHP
PHP中ADODB类详解
2008/03/25 PHP
php获取qq用户昵称和在线状态(实例分析)
2013/10/27 PHP
通过php添加xml文档内容的方法
2015/01/23 PHP
IE和Firefox下javascript的兼容写法小结
2008/12/10 Javascript
javascript中的float运算精度实例分析
2010/08/21 Javascript
js汉字排序问题 支持中英文混排,兼容各浏览器,包括CHROME
2011/12/20 Javascript
jquery获取tr并更改tr内容示例代码
2014/02/13 Javascript
js获取表格的行数和列数的方法
2015/10/23 Javascript
分享经典的JavaScript开发技巧
2015/11/21 Javascript
早该知道的7个JavaScript技巧
2016/06/21 Javascript
基于JS如何实现给字符加千分符(65,541,694,158)
2016/08/03 Javascript
通过扫描二维码打开app的实现代码
2016/11/10 Javascript
老生常谈原生JS执行环境与作用域
2016/11/22 Javascript
Bootstrap组合上、下拉框简单实现代码
2017/03/06 Javascript
Angular动态添加、删除输入框并计算值实例代码
2017/03/29 Javascript
详解如何提高 webpack 构建 Vue 项目的速度
2017/07/03 Javascript
详解JavaScript中的六种错误类型
2017/09/21 Javascript
原生JS实现轮播图效果
2018/10/12 Javascript
优雅的elementUI table单元格可编辑实现方法详解
2018/12/23 Javascript
浅谈KOA2 Restful方式路由初探
2019/03/14 Javascript
Vuex的actions属性的具体使用
2019/04/14 Javascript
JS求1到任意数之间的所有质数的方法详解
2019/05/20 Javascript
解决vue一个页面中复用同一个echarts组件的问题
2020/07/19 Javascript
解决vue中axios设置超时(超过5分钟)没反应的问题
2020/09/04 Javascript
python中stdout输出不缓存的设置方法
2014/05/29 Python
Python配置文件解析模块ConfigParser使用实例
2015/04/13 Python
Python实现判断并移除列表指定位置元素的方法
2018/04/13 Python
Python openpyxl模块原理及用法解析
2020/01/19 Python
QML实现钟表效果
2020/06/02 Python
编写类String 的构造函数、析构函数和赋值函数
2012/09/09 面试题
银行实习生的自我评价
2013/12/09 职场文书
教师岗位职责范本
2013/12/29 职场文书
实习生求职自荐信
2014/02/07 职场文书
写好求职信的技巧解密
2019/05/14 职场文书
Vue Element-ui表单校验规则实现
2021/07/09 Vue.js