>>> from env_helper import info; info()
页面更新时间: 2023-12-27 09:28:52
运行环境:
    Linux发行版本: Debian GNU/Linux 12 (bookworm)
    操作系统内核: Linux-6.1.0-16-amd64-x86_64-with-glibc2.36
    Python版本: 3.11.2

4.1. 掌握字符串的基本用法

无名氏说:编程有两件事,一件是处理数值.另一件是处理字符串。

要我说,对于商业应用编程来说,处理字符串的代码可能超过八成,所以掌握字符串的基本用法尤其重要。 通过Python教程,读者已经掌握了基本的字符串字面量语法,比如 ur 前缀等, 但对于怎么 更好地编写多行的字符串字面量,仍然有个小技巧值得向大家推介。

>>> s=("select * "
>>>    "from atable "
>>>    "where afield='value'")
>>> s
"select * from atable where afield='value'"

这就是利用Python遇到未闭合的小括号时会自动将多行代码拼接为一行和把相邻的两 个字符串字面摄拼接在一起的特性做到的。 相比使用3个连续的单(双)引号,这种方式不会把换行符和前导空格也当作字符串的一部分, 则更加符合用户的思维习惯。

除了这个小技巧,也许你已经听说过Python中的字符串其实有 strunicode 两种。 是的,的确如此,虽然在Python 3中已经简化为一种。

>>> a="hi"
>>> isinstance(a,str)
True
>>> b=u"Hi"
>>> isinstance(b,str)
True

但如果你还在编写运行在Python 2上的 程序,当需要判断变量是否为字符串时,需要注意了:

判断一个变量 s 是不是字符串应使用 isinstance(s,basestring) , 注意这里的参数是 basestring 而不是 str

同样的问题,包括 isinstance(b,unicode) ,这个在 Python3内无法执行,Python2内可以运行。

isinstance(a,str) 用于判断一个字符串是不是普通字符串,也就是说其类型是否为 str ; 因此当被判断的字符串为 Unicode 的时候,返回 False 。 同样, isinstance(a,unicode) 用来判断一个字符串是不是Unicode。 因此要正确判断一个变 量是不是字符串,应该使用isinstance(s,basestring),因为basestring才是是strUnicode的 基类,包含了普通字符串和Unicode类型。

接下来正式开始学习字符串的基本用法。与其他书籍、手册不同,我们将通过性质判 定、査找替换、分切与连接、变形、填空与刪减等5个方面来学习。

首先是性质判定, str 对 象有以下几个方法: isa]num()isinpha()isdigit()islower()isuppier()isspace()istitle()startswith(prefix, start[, end]])endswith(suffix[,start[,end]) 。 前面几个 is*() 形式的函数很简单,顾名思义无非是判定是否数字、字母、大小写、空白符之类的, istitle() 作为东方人用得少些,它是判定字符串是否每个单词都有且只有第一个字母是大写的。

>>> assert "Hello World".istitle()==True
>>> assert "Hello world".istitle()==False

相对于 is*() 这些“小儿科”来说,需要注意的是*with()函数族可以接受可选的startend参数, 善加利用,可以优化性能。 另外,自Python 2-5版本起,*with()函数族的prefix 参数可以接受tuple类型的实参,当实参中的某个元素能够匹配时,即返回True

接下来是査找与替换,count(sub[, start[,end]])find( sub[, start[,end]])index( sub[, start[,end]])rfind( sub[, start[,end]])rindex( sub[,start[, end]])这些方法都接受 startend参数,善加利用,可以优化性能。其中count()能够査找子串sub在字符串中出 现的次数,这个数值在调用replace方法的时候用得着。此外,需要注意find()index()方法的不同:find()函数族找不到时返回-1, index()函数族则抛出ValueError异常。但对于判 定是否包含子串的判定并不推荐调用这些方法,而是推荐使用innot in操作符。

>>> str="Test if a string contains some spacial substrings"
>>> if str.find("some")!=-1:
>>>     print("yes it contains")
yes it contains
>>> if "some" in str:
>>>     print("yes it contains using in ")
yes it contains using in

replace(old, new[,count])用以替换字符串的某些子串,如果指定count参数的话,就最多 替换count次,如果不指定,就全部替换(跟其他语言不太一样,要注意了)。

然后要掌_字符串的分切与连接,关于连接,会有一节专门进行讲述,在这里,专讲分切。 partition(sep)rpartition(sep)splitlines([keepends])split([sep [,maxsplit]])rsplit([sep[,maxsplit]), 别看这些方法好像很多,其实只要弄清楚partition()spht()就可以了。*partition()涵数族是 2.5版木新增的方法,它接受一个字符串参数,并返冋一个3个元素的元组对象。如果sep没出现在母串中,返回值是(set,",");否则,返回值的第一个元素是sep左端的部分,第二个元素是sep自身,第三个元素是sep右端的部分。而split()的参数maxsplit是分切的次数,即最大的分切次数,所以返回值最多有maxsplit+1个元索。但split()有不少小陷阱需要注意, 比如对于字符串ss.split()s.split("")的返回值是不相同的。

>>> "hello world".split()
['hello', 'world']
>>> "hello    world".split(" ")
['hello', '', '', '', 'world']

产生差异的原因在于:当忽略sep参数或sep参数为None时与明确给sep賦予字符串值 时,split()采用两种不同的算法。对于前者,split()先去除字符申两端的空白符,然后以任意 长度的空内符串作为界定符分切字符串(即连续的空白符串被当作单一的空内符看待);对于 后者则认为两个连续的sep之间存在一个空字符串。因此对于空字符串(或空白符串),它们 的返回值也是不同的。

>>> "".split()
[]
>>> "".split(" ")
['']

掌握了 split() ,可以说字符串最大的陷阱已经跨过去了。

下面是关于变形的内容。 lower()upper()capitaliz()swapcase()title() 这些无非是大小写切换的小事。 不过需要注意的是 title() 的功能是将每一个单词的首字母大写,并将单词中的非首字母转换为小写 (英文文章的标题通常是这种格式)。

>>> "hello wOrld".capitalize()
'Hello world'
>>> "hello wOrld".swapcase()
'HELLO WoRLD'
>>> "hello wOrld".title()
'Hello World'

因为函数并不去除字符串两端的空白符也不会把连续的空白符替换为一个空格, 所以不能把 title() 理解先以空白符分切字符串, 然后调用 capitalize() 处理每个字词以使其 首宇母大写,再用空格将它们连接在一起。 如果你有这样的需求,建议使用 string 模块中的 capwords(s) 函数, 它能够去除两端的空白符,再将连续的空白符用一个空格代替。

>>> " hello      world".title()
' Hello      World'
>>> import string
>>> string.capwords("  hello    world")
'Hello World'

看,它们的结果是不相同的。

最后是删减与填充。

删减在文本处理是很常用,我们 常常得把字符串描头去尾,就用得上它们。 如果 strip([chars])lstrip([chars])mrip(fchars]) 中的 chars 参数没有指定, 就是删除空白符,空白符由 string.whitespace 常量定义。 填充则 常用于字符串的输出,借助它们能够排出漂亮的版面。 center(width[, fillchar])ljust(width [,:fillchar]) , ijust(width[,fillchar])zfill(width)expandtabs([tabsize]) ,看,有了它们,居中、 左对齐、右对齐什么的完全不在话下。 这些方法中的 fillchar 参数是指用以填充的字符,默认 是空格。 而 zfill() 中的 z 是指 zero ,所以顾名思义,即是以 字符 0 进行填充, 在输出数值时比较常用。 expandtabs()tabsize 参数默认为 8 ,它的功能是把字符串中的制表符(tab) 转换为适当数字的空格。