X Tutup
>所以你施舍的时候,不可在你前面吹号,像那假冒为善的人,在会堂里和街道上所行的,故意要得人的荣耀。我实在告诉你们,他们已经得了他们的上次。你施舍的时候,不要叫左手知道右手所作的。要叫你施舍的事行在暗中,你父在暗中察看,必然报答你。(MATTHEW 6:2-4) #字符串(4) 虽然已经对字符串有了了解,但,因为人对字符串的要求比较多,特别是在输出格式上,要满足一定的样式要求。 ##字符串格式化输出 什么是格式化?在维基百科中有专门的词条,这么说的: >格式化是指对磁盘或磁盘中的分区(partition)进行初始化的一种操作,这种操作通常会导致现有的磁盘或分区中所有的文件被清除。 不知道你是否知道这种“格式化”。显然,此格式化非我们这里所说的,我们说的是字符串的格式化,或者说成“格式化字符串”,表示的意思是: >格式化字符串,是C、C++等程序设计语言printf类函数中用于指定输出参数的格式与相对位置的字符串参数。其中的转换说明(conversion specification)用于把随后对应的0个或多个函数参数转换为相应的格式输出;格式化字符串中转换说明以外的其它字符原样输出。 这也是来自维基百科的定义。在这个定义中,是用C语言作为例子,并且用了其输出函数来说明。在Python中,也有同样的操作——`print`语句(Python 2)、`print()`函数(Python 3),此前我们已经了解一二了。此处将详述之。 如果将维基百科的定义再通俗化,所谓字符串格式化化,就是要先制定一个模板,在这个模板中某个或者某几个地方留出空位来,然后在那些空位填上字符串,并且在显示结果中,字符串要符合空位置所设定的约束条件。 那么,那些空位,需要用一个符号来表示,这个符号通常被叫做占位符(仅仅是占据着那个位置,并不是输出的内容)。 >>> "I like %s" 'I like %s' 在这个字符串中,有一个符号:`%s`,就是一个占位符,这个占位符可以被其它的字符串代替。比如: >>> "I like %s" % "python" 'I like python' >>> "I like %s" % "Pascal" 'I like Pascal' 这是曾经较为常用的一种字符串输出方式。注意“曾经”,言下之意,现在不怎么太提倡了。 的确如此,现在提倡使用`.format()`,这是自Python 2.6开始引入的。所以,从现在开始,本教程详细介绍`string.format()`的使用方法,而对用`%`进行格式化输出的方式,仅仅局限在上面的样式。读者在阅读其它代码的时候,也能遇到使用`%`的,那时候你心中默默说一句“落伍了”,然后翻译成`string.format()`即可。 `.format()`是字符串的一个方法。你在交互模式中,输入`dir(str)`,会看到如下的内容: >>> dir(str) ['__add__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__gt__', '__hash__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'capitalize', 'casefold', 'center', 'count', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'format_map', 'index', 'isalnum', 'isalpha', 'isdecimal', 'isdigit', 'isidentifier', 'islower', 'isnumeric', 'isprintable', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'maketrans', 'partition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill'] 这里所列出来的,就是字符串`str`的所有属性和方法。 在这里先下一点毛毛雨。在Python中一切皆对象,所谓对象,就是一个具体东西。桌椅板凳,花花草草,动物植物,包括人,还有程序要找的那个“对象”,都是对象(不用追求严格定义,暂且模模糊糊知道大概即可,大概都不知道,也无妨),凡是对象都有属性和方法(至于属性和方法的定义,待后面说明)。刚才用`dir(str)`所返回的结果,就是字符串的属性和方法。 在返回结果中,别的先不看,只看`format`。有你的慧眼找一找,有没有发现? 继续不要离开交互模式,输入: >>> help(str.format) 这是要看字符串的`format()`方法的文档。只有通过阅读文档,我们才能了解它使做什么的。 返回结果是: Help on method_descriptor: format(...) S.format(*args, **kwargs) -> str Return a formatted version of S, using substitutions from args and kwargs. The substitutions are identified by braces ('{' and '}'). `S.format(*args, **kwargs)`,重点看括号里面的,`*args`表示传入一种类型的参数,`**arg`表示传入另外一种类型的参数。 又遇到新名词——参数——还是不用搭理它,只管继续——因为“发展是硬道理”! 你暂且阅读文档,不理解也没关系。下面用示例来说明使用方法。 >>> "I like {0} and {1}".format("python", "canglaoshi") 'I like python and canglaoshi' 在交互模式中,输入了字符串`"I like {0} and {1}"`,并且其中用`{0}`和`{1}`占据了两个位置,它们就是占位符。然后使一个非常重要的点`.`。 这个点`.`非常重要,它是从对象引出它的属性或方法的工具,就如同汉语中的“的”一样。 比如“老齐的爱好”,“老齐”是那个对象,“爱好”就是一个方法,两者中间的那个“的”就相当于一个英文的点`.`,于是可以写成`老齐.爱好`,就可以表明上述的含义了。 `format("python", "canglaoshi")`是字符串格式化输出的方法,传入了两个字符串,它们分别对应这`"I like {0} and {1}"`里的那两个占位符,而且使按照顺序对应的,即第一个参数传入的`"pytohn"`,对应着`{0}`,第二参数传入的`"canglaoshi"`对应着`{1}`。 你还可以这样试试,就理解更深刻了。 >>> "I like {1} and {0}".format("python", "canglaoshi") 'I like canglaoshi and python' 请仔细观察找区别。 `format()`方法的返回值是一个字符串——`'I like python and canglaoshi'`。 再对照`help(str.format)`得到的文档,看一看,是不是理解文档的含义了呢? 一定要会阅读文档,这是学习语言的根本。 既然是“格式化”,就要指定一些格式,让输出的结果符合指定的样式。 >>> "I like {0:10} and {1:>15}".format("python", "canglaoshi") 'I like python and canglaoshi' 现在有格式了。`{0:10}`表示第一个位置,有10个字符那么长,并且放在这个位置的字符是左对齐;`{1:>15}`表示第二个位置,有15个字符那么长,并且放在这个位置的字符是右对齐。 >>> "I like {0:^10} and {1:^15}".format("python", "canglaoshi") 'I like python and canglaoshi ' 现在是居中对齐了。 >>> "I like {0:.2} and {1:^10.4}".format("python", "canglaoshi") 'I like py and cang ' 这个有点复杂,我们一点一点的解释。 `{0:.2}`:`0`说明是第一个位置,对应传入的第一个字符串。`.2`表示对于传入的字符串,截取前两个,并放到第一个位置,注意的是,在`:`后面和`.`号前面,没有任何数字,意思是该位置的长度自动适应即将放到该位置的字符串。 `{1:^10.4}`:`1`说明是第二个位置,对应传入的第二个字符串。`^`表示放到该位置的字符串要居中;`10.4`表示该位置的长度是10个字符串那么长,但,即将放入该位置的字符串应该仅仅有4个字符那么长,也就是要从传入的字符串`"canglaoshi"`中截取前四个字符,即为`"cang"`。 再看结果,对照上述解释。 向`format()`中,除了能够传入字符串,还可以传入数字(包括整数和浮点数),而且也能有各种花样。 >>> "She is {0:d} years old and the breast is {1:f}cm".format(28, 90.1415926) 'She is 28 years old and the breast is 90.141593cm' `{0:d}`表示在第一个位置放一个整数;`{1:f}`表示在第二个位置放一个浮点数,那么浮点数的小数位数,是默认的。下面在这个基础上,可以再做一些显示格式的优化。 >>> "She is {0:4d} years old and the breast is {1:6.2f}cm".format(28, 90.1415926) 'She is 28 years old and the breast is 90.14cm' `{0:4d}`表示第一个位置的长度是4个字符,并且默认状态下,填充到该位置的整数是右对齐。 `{1:6.2f}`表示第二个位置的长度使6个字符,并且填充到该位置的浮点数要保留两位小数,默认也是右对齐。 >>> "She is {0:04d} years old and the breast is {1:06.2f}cm".format(28, 90.1415926) 'She is 0028 years old and the breast is 090.14cm' `{0:04d}`和`{1:06.2f}`与前述例子不同的在于在声明位置长度的数字前面多了`0`,其含义是在数字前面,如果位数不足,则补`0`。 以上的输出方式中,我们只讨论了`format(*args, **kwargs)`中的`*args`部分。还有另外一种方式,则是与`**kwargs`有关的(关于这两种参数的含义,本教程后面有专门介绍)。 >>> "I like {lang} and {name}".format(lang="python", name="canglaoshi") 'I like python and canglaoshi' 一种被称为“字典格式化”,这里仅仅列一个例子。关于“字典”,本教程后续会有的。 >>> data = {"name":"Canglaoshi", "age":28} >>> "{name} is {age}".format(**data) 'Canglaoshi is 28' 用`format()`做字符串格式化输出,真的很简洁,堪称优雅。 但`format()`毕竟只是字符串的方法之一,还有更多方法等待研究。 ##常用的字符串方法 字符串的方法很多,前面已经通过`dir(str)`查看过了。 那么多方法,不会一一介绍,要了解某个具体的含义和使用方法,最好是使用`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考虑到有不少人可能有这个习惯,因此就帮助程序员把这些空格去掉。 方法是: - `S.strip()`:去掉字符串的左右空格 - `S.lstrip()`:去掉字符串的左边空格 - `S.rstrip()`:去掉字符串的右边空格 例如: >>> b = " hello " #两边有空格 >>> b.strip() 'hello' >>> b ' hello ' 特别注意,原来的值没有变化,而是新返回了一个结果。 >>> b.lstrip() #去掉左边的空格 'hello ' >>> b.rstrip() #去掉右边的空格 ' hello' ###字符大小写的转换 对于英文,有时候要用到大小写转换。最有名驼峰命名,里面就有一些大写和小写的参合。如果有兴趣,可以来这里看[自动将字符串转化为驼峰命名形式的方法](https://github.com/qiwsir/algorithm/blob/master/string_to_hump.md)。 在Python中有下面一些字符串的方法,用来实现各种类型的大小写转化 - `S.upper()`:S中的字母大写 - `S.lower()`:S中的字母小写 - `S.capitalize()`:首字母大写 - `S.isupper()`:S中的字母是否全是大写 - `S.islower()`:S中的字母是否全是小写 - `S.istitle()`:S中字符串中所有的单词拼写首字母是否为大写,且其他字母为小写(标题都这么写) 看例子: >>> 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' 这种拼接,是不是简单呢? 虽然不能把所有方法穷尽,但读者完全可以仿照上述流程研究其它方法。 字符串的问题还要继续,因为中文和英文还有很大区别。 ------ [总目录](./index.md)   |   [上节:字符串(3)](./108.md)   |   [下节:字符编码](./110.md) 如果你认为有必要打赏我,请通过支付宝:**qiwsir@126.com**,不胜感激。
X Tutup