码迷,mamicode.com
首页 > 编程语言 > 详细

Python3字符串各种内置函数详解

时间:2016-06-24 15:24:07      阅读:286      评论:0      收藏:0      [点我收藏+]

标签:



Python3访问字符串

    Python不支持单字符类型,单字符在Python中也是作为一个字符串来使用;

    字符串切片截取;

空值

空值是Python里一个特殊的值,用None表示。None不能理解为0,因为0是有意义的,而None是一个特殊的空值。

最后,理解变量在计算机内存中的表示也非常重要。当我们写:

a = ‘ABC‘

时,Python解释器干了两件事情:

  1. 在内存中创建了一个‘ABC‘的字符串;

  2. 在内存中创建了一个名为a的变量,并把它指向‘ABC‘

也可以把一个变量a赋值给另一个变量b,这个操作实际上是把变量b指向变量a所指向的数据,例如下面的代码:

a = ‘ABC‘
b = a a = ‘XYZ‘
print(b)

最后一行打印出变量b的内容到底是‘ABC‘呢还是‘XYZ‘?如果从数学意义上理解,就会错误地得出ba相同,也应该是‘XYZ‘,但实际上b的值是‘ABC‘,让我们一行一行地执行代码,就可以看到到底发生了什么事:

执行a = ‘ABC‘,解释器创建了字符串‘ABC‘和变量a,并把a指向‘ABC‘

技术分享

执行b = a,解释器创建了变量b,并把b指向a指向的字符串‘ABC‘

技术分享

执行a = ‘XYZ‘,解释器创建了字符串‘XYZ‘,并把a的指向改为‘XYZ‘,但b并没有更改:

技术分享

所以,最后打印变量b的结果自然是‘ABC‘了。




字符编码

我们已经讲过了,字符串也是一种数据类型,但是,字符串比较特殊的是还有一个编码问题。

因为计算机只能处理数字,如果要处理文本,就必须先把文本转换为数字才能处理。最早的计算机在设计时采用8个比特(bit)作为一个字节(byte),所以,一个字节能表示的最大的整数就是255(二进制11111111=十进制255),如果要表示更大的整数,就必须用更多的字节。比如两个字节可以表示的最大整数是65535,4个字节可以表示的最大整数是4294967295。

由于计算机是美国人发明的,因此,最早只有127个字母被编码到计算机里,也就是大小写英文字母、数字和一些符号,这个编码表被称为ASCII编码,比如大写字母A的编码是65,小写字母z的编码是122。

但是要处理中文显然一个字节是不够的,至少需要两个字节,而且还不能和ASCII编码冲突,所以,中国制定了GB2312编码,用来把中文编进去。

你可以想得到的是,全世界有上百种语言,日本把日文编到Shift_JIS里,韩国把韩文编到Euc-kr里,各国有各国的标准,就会不可避免地出现冲突,结果就是,在多语言混合的文本中,显示出来会有乱码。

>>> fruit=‘banana‘
>>> letter=fruit[1] #从fruit中选择索引为1的字符并将他赋给
letter
>>> letter‘a‘>>>

除了数字,Python还可以操纵字符串,可以一几种不同的方式表达。他们可以包含在单引号(‘...’)或者("...")双引号中,其结果相同

>>> ‘apple‘‘apple‘
>>> ‘doesn\‘t‘  #可以用\’转义字符
"doesn‘t"
>>> "doesn‘t"   #或者用两个不一样的引号
"doesn‘t"
>>> ‘"Yes,"he said‘
‘"Yes,"he said‘
>>> "\"Yes,\"he said"
‘"Yes,"he said‘
>>> ‘"Isn\‘t," seh said.‘
‘"Isn\‘t," seh said.‘

在交互式解释器,输出字符串包含在引号和特殊字与反斜杠转义。虽然这时有所不同,从输入(包含引号可以改变),这两个字符串是一样的。如果字符串包含双引号和单引号,该字符串给括在双引号中,否则被括在单引号中。print() 函数生成一个更可读的输出。\可用于转义引号。

>>> ‘"Isn\‘t"she said.‘‘"Isn\‘t"she said.‘
>>> print(‘"Isn\‘t"she said.‘)
"Isn‘t"she said.
>>> >>> s=‘First line.\nSecond line.‘ #\n表示换行=
>>> s‘First line.\nSecond line.‘
>>> print(s)First line.Second line.
>>>

如果你不想被\前缀解释为特殊字符,你可以使用原始字符串之前的字符串前加一个 r ;

>>> print(‘C:\some\name‘)
C:\some
ame
>>> print(r‘C:\some\name‘) C:\some\name
>>>

字符串连接

1:字符串可以通过+或者*操作符连接;

>>> #重复3次‘un’之后,后面加上‘ium’
>>> 3*‘um‘+‘ium‘
‘umumumium‘
>>>

2:两个或多个字符串(封闭的引号隔开)相邻之间自动连接;

>>> ‘py‘‘thon‘ #中间留不留空格效果一样
‘python‘
>>>

注:这只适用于两个字符串,而不是用于变量或者表达式;

>>> prefix=‘py‘
>>> preix ‘thon‘
SyntaxError: invalid syntax
>>> (‘un‘*3)‘ium‘
SyntaxError: invalid syntax
>>>

3:如果你想连接两个变量,使用+操作符可以实现

>>> prefix=‘py‘
>>> prefix+‘thon‘
‘python‘
>>>

4:一下字符串有其有用,当你想要打破输入一个长字符串;

>>> text=(‘My name is Anne,This is My page,‘
‘Welcome to my house!‘)
>>> text‘My name is Anne,This is My page,Welcome to my house!‘
>>> 

字符串访问

1:字符串可以被索引(下标)访问;没有单独的字符类型,一个字符就是一个
字符串的大小;

>>> word=‘python‘
>>> word[0]     #在位置0,word的第一个字符
‘p‘
>>> word[5]
‘n‘
>>>

2:索引也有可能是负数,从右边开始计数;

>>> word[-1]
‘n‘
>>> word[-6]
‘p‘
>>>

注意:-0和0是一样的,负数索引从零开始;

字符串切片

>>> word[0:2]       #从零位置到2的字符

‘py‘

>>> word[2:5]
‘tho‘

>>>

注意:一开始总是被包括,最后总是被排除在外,这确保s[:i]+s[i:]总是等价于s

>>> word=‘python‘

>>> word[:2]+word[2:]
‘python‘

>>> word[:4]+word[4:]
‘python‘

>>> word[:8]+word[:8]
‘pythonpython‘

>>> word[:1]+word[1:]
‘python‘>>>

切片索引可以使用默认值,s[:i]省略第一个索引默认为零;s[i:]省略第二个索引默认被切片的字符串的大小。

试图使用太大的索引将导致一个错误。

>>> word[89]    #word只有6个字母Traceback (most recent call last):
  File "<pyshell#5>", line 1, in <module>
    word[89]IndexError: string index out of range
>>>

但是,此种情况下是可以使用切片的:

>>> word[2:89]
‘thon‘
>>>

上次已经说过Python字符串不能改变——他们是不可变的。因此,指定字符串中的索引位置导致一个错误。

>>> word[0]=‘J‘Traceback (most recent call last):
  File "<pyshell#7>", line 1, in <module>
    word[0]=‘J‘TypeError: ‘str‘ object does not support item assignment>>> word[2:]=‘py‘Traceback (most recent call last):
  File "<pyshell#8>", line 1, in <module>
    word[2:]=‘py‘TypeError: ‘str‘ object does not support item assignment>>> ‘j‘+word[1:]
‘jython‘
>>>

字符串处理是非常常用的技能,但 Python 内置字符串方法太多,常常遗忘,为了便于快速参考,特地依据 Python 3.5.1 给每个内置方法写了示例并进行了归类,便于大家索引。

PS: 可以点击概览内的绿色标题进入相应分类或者通过右侧边栏文章目录快速索引相应方法。

String Method 概览

字符串大小写转换

str.capitalize()
str.lower()
str.casefold()
str.swapcase()
str.title()
str.upper()

字符串格式输出

str.center(width[, fillchar])
str.ljust(width[, fillchar]);
str.rjust(width[, fillchar])
str.zfill(width)
str.expandtabs(tabsize=8)
str.format(^args, ^^kwargs)
str.format_map(mapping)

字符串搜索定位与替换

str.count(sub[, start[, end]])
str.find(sub[, start[, end]]); str.rfind(sub[, start[, end]])
str.index(sub[, start[, end]]); str.rindex(sub[, start[, end]])
str.replace(old, new[, count])
str.lstrip([chars]); str.rstrip([chars]); str.strip([chars])
static str.maketrans(x[, y[, z]]); str.translate(table)

字符串的联合与分割

str.join(iterable)
str.partition(sep);
str.rpartition(sep)
str.split(sep=None, maxsplit=-1);
str.rsplit(sep=None, maxsplit=-1)
str.splitlines([keepends])

字符串条件判断

str.endswith(suffix[, start[, end]]);
str.startswith(prefix[, start[, end]]) str.isalnum()
str.isalpha()
str.isdecimal();
str.isdigit();
str.isnumeric()
str.isidentifier()
str.islower()
str.isprintable()
str.isspace()
str.istitle()
str.isupper()

字符串编码

str.encode(encoding="utf-8", errors="strict")

大小写转换


1)str.capitalize()
——返回的字符串的首字母大写,其余小写。

>>> word.capitalize()‘Python‘>>> 

2)str.lower()
——把字符串改为小写的形式

>>> name="ANNE"
>>> name.lower()
‘anne‘
>>>

3)str.upper()
——把字符串改为大写的形式

>>> name="anne"
>>> name.upper()
‘ANNE‘
>>>

需要注意的是 s.upper().isupper() 不一定为 True。

4)str.casefold()
——将字符串转换成小写,Unicode编码中凡是有对应的小写形式的,都会转换;

>>> ‘FAFD‘.casefold()
‘fafd‘
>>> ‘徐XU‘.casefold()
‘徐xu‘
>>>

5)str.swapcase()
——对字符串字母的大小写进行反转。

>>> ‘dao‘.swapcase()
‘DAO‘
>>> ‘Daio‘.swapcase()
‘dAIO‘
>>>

但是需要注意的是:str.swapcase().swapcase()==str不一定为真

6)str.title()
——将字符串中每个“单词”首字母。其判断“单词”的依据则是基于空格和标点,所以应对英文撇好所有格或一些英文大写的简写时,会出错。
注意title和capitalize的区别;

>>> ‘hello world‘.capitalize()
‘Hello world‘
>>> ‘hello world‘.title()
‘Hello World‘
>>>

字符串格式输出


1)str.center(width[, fillchar])
——将字符串按照给定的宽度居中显示,可以给定特定的字符填充多余的长度,如果指定的长度小于字符串长度,则返回原字符串。

>>> ‘Anne‘.center(10)
‘   Anne   ‘
>>> ‘Anne‘.center(10,‘*‘)
‘***Anne***‘
>>> ‘Anne‘.center(5)
‘ Anne‘

2)str.ljust(width[, fillchar]);
str.rjust(width[, fillchar])
——返回指定长度的字符串,字符串内容居左(右)如果长度小于字符串长度,则返回原始字符串,默认填充为 ASCII 空格,可指定填充的字符串。

>>> ‘Anne‘.ljust(3)
‘Anne‘
>>> ‘Anne‘.ljust(5)
‘Anne ‘
>>> ‘Anne‘.ljust(3,‘~‘)
‘Anne‘
>>> ‘Anne‘.ljust(10,‘~‘)
‘Anne~~~~~~‘
>>>

3)str.zfill(width)
——用 ‘0‘ 填充字符串,并返回指定宽度的字符串。

>>> ‘77‘.zfill(5)
‘00077‘
>>> ‘-77‘.zfill(5)
‘-0077‘
>>> ‘qi‘.zfill(5)
‘000qi‘
>>> ‘--‘.zfill(5)
‘-000-‘
>>> ‘ ‘.zfill(5)
‘0000 ‘
>>> ‘  ‘.zfill(5)
‘000  ‘
>>> ‘‘.zfill()      #括号里面一定要添加数字 Traceback (most recent call last):  File "<pyshell#8>", line 1, in <module>    ‘‘.zfill()TypeError: zfill() takes exactly 1 argument (0 given) >>> ‘‘.zfill(5)
‘00000‘
>>> ‘qiqiq‘.zfill(5)
‘qiqiq‘
>>>

4)str.expandtabs(tabsize=8)
——用指定的空格替代横向制表符,使得相邻字符串之间的间距保持在指定的空格数以内。tab 符号默认的空格数是 8。
>>> tab = ‘1\t23\t456\t7890\t1112131415\t161718192021‘
>>> tab.expandtabs()
‘1 23 456 7890 1112131415 161718192021‘
>>> tab.expandtabs(4)
‘1 23 456 7890 1112131415 161718192021‘
>>>
5)str.format(^args, ^^kwargs)
——格式化字符串的语法比较繁多,官方文档已经有比较详细的 examples,我上一节也已经介绍了,这里就不冗余解释了;
6)str.format_map(mapping)
——类似 str.format(*args, **kwargs) ,不同的是 mapping 是一个字典对象。

>>> People = {‘name‘:‘john‘, ‘age‘:56}
>>> ‘My name is {name},i am {age} old‘.format_map(People)
‘My name is john,i am 56 old‘
>>>

字符串搜索定位与替换


1)str.count(sub[, start[, end]])
——返回指定字符在[指定位置的]str出现的次数

>>> text = ‘outer protective covering‘
>>> text.count(‘e‘)
4
>>> text.count(‘e‘, 5, 11)
1
>>> text.count(‘e‘, 5, 10)
0

2)str.find(sub[, start[, end]]); str.rfind(sub[, start[, end]])
——返回指定字符在[指定位置的]str出现的索引

>>> text = ‘outer protective covering‘
>>> text.find(‘er‘)
3
>>> text.find(‘er‘, 3)
3
>>> text.find(‘er‘, 4)
20
>>> text.find(‘er‘, 4, 21)      #找不到就会返回-1; -1
>>> text.rfind(‘er‘)
20
>>> text.lfind(‘er‘)        #没有这个方法 Traceback (most recent call last):  File "<pyshell#16>", line 1, in <module>    text.lfind(‘er‘)AttributeError: ‘str‘ object has no attribute ‘lfind‘>>> text.rfind(‘er‘, 20)
20
>>> text.rfind(‘er‘, 20, 21)        #找不到返回-1
-1
>>>

3)str.index(sub[, start[, end]]);
str.rindex(sub[, start[, end]])
——与 find() rfind() 类似,不同的是如果找不到,就会引发 ValueError。

>>> text
‘outer protective covering‘
>>> text.index(‘e‘)
3
>>> text.index(‘e‘,4)
10
>>> text.index(‘e‘,4,9)     #找不到就会引发ValueError错误 Traceback (most recent call last):  File "<pyshell#22>", line 1, in <module>    text.index(‘e‘,4,9)ValueError: substring not found

4)str.replace(old, new[, count])
——1)Python replace()方法把字符串中的old(旧字符替)换成new(新字符)。如果指定第三个参数max,则替换不超过max。
2)用法:str.replace(old,new[,max])
3)参数解释
●old---将被替换的子字符串
●new---新字符串,用于替换old子字符串
●max---可选字符串,替换不超过max次

此方法已经在字符串解说(上)中介绍过了。只给出如下实例,不做过多冗余;
>>> ‘Anne is very very good guy‘.replace(‘very‘,‘so‘)‘Anne is so so good guy‘>>> ‘Anne is very very good guy‘.replace(‘very‘,‘so‘,0)‘Anne is very very good guy‘>>> ‘Anne is very very good guy‘.replace(‘very‘,‘so‘,1)‘Anne is so very good guy‘>>> ‘Anne is very very good guy‘.replace(‘very‘,‘so‘,2)‘Anne is so so good guy‘>>> ‘Anne is very very good guy‘.replace(‘very‘,‘so‘,3)‘Anne is so so good guy‘>>> 

5)str.lstrip([chars]); #chars --指定截取的字符。
str.rstrip([chars]);
str.strip([chars]);
——Python lstrip() 方法用于截掉字符串左边的空格或指定字符。返回截掉字符串左边的空格或指定字符后生成的新字符串。

>>> ‘   Hello World  ‘.lstrip()
‘Hello World  ‘
>>> ‘777Hello World77‘.lstrip(‘7‘)
‘Hello World77‘
>>>    ——Python rstrip() 删除 string 字符串末尾的指定字符(默认为空格).返回删除 string 字符串末尾的指定字符后生成的新字符串。

>>> ‘   Hello World  ‘.rstrip()
‘   Hello World‘
>>> ‘777Hello World77‘.rstrip(‘7‘)
‘777Hell    ——Python strip() 方法用于移除字符串头尾指定的字符(默认为空格)。返回移除字符串头尾指定的字符生成的新字符串 >>> ‘   Hello World  ‘.strip() ‘Hello World‘ >>> ‘77Hello World77‘.strip(‘77‘) ‘Hello World‘ >>>

6)static str.maketrans(x[, y[, z]]);
str.translate(table)
——maketrans 是一个静态方法,用于生成一个对照表,以供 translate 使用。
如果 maketrans 仅一个参数,则该参数必须是一个字典,字典的 key 要么是一个 Unicode 编码(一个整数),要么是一个长度为 1 的字符串,字典的 value 则可以是任意字符串、None或者 Unicode 编码。

>>> a = ‘dobi‘
>>> ord(‘o‘)
111
>>> ord(‘a‘)
97
>>> hex(ord(‘狗‘))
‘0x72d7‘
>>> b = {‘d‘:‘dobi‘, 111:‘ is ‘, ‘b‘:97, ‘i‘:‘\u72d7\u72d7‘}
?>>> table = str.maketrans(b)
?>>> a.translate(table)
?‘dobi is a狗狗‘
>>>

也可以简单一点生成对照表:

  >>> a=‘dobi‘
  >>> b = {‘d‘:‘dobi‘, ‘o‘:‘ is ‘, ‘b‘:‘a‘, ‘i‘:‘dog‘} 
 
 >>> table=str.maketrans(b)  
 >>> a.translate(table)
  ‘dobi is adog

——如果 maketrans 有两个参数,则两个参数形成映射,且两个字符串必须是长度相等;如果有第三个参数,则第三个参数也必须是字符串,该字符串将自动映射到 None


字符串的联合与分割


1)str.join(iterable)
——用指定的字符串,连接元素为字符串的可迭代对象。
str.join(seq)——以 str 作为分隔符,将 seq 中所有的元素(的字符串表示)合并为一个新的字符串

>>> ‘-‘.join([‘2016‘,‘06‘,‘23‘])
‘2016-06-23‘

>>> ‘-‘.join([])
‘‘
>>> ‘-‘.join([None])
Traceback (most recent call last):  File "<pyshell#2>", line 1, in <module>    ‘-‘.join([None])TypeError: sequence item 0: expected str instance, NoneType found
>>> ‘-‘.join([‘‘])
‘‘
>>> ‘-‘.join([‘2016‘,‘06‘,b‘23‘])   #byte为非字符串
Traceback (most recent call last):  File "<pyshell#4>", line 1, in <module>    ‘-‘.join([‘2016‘,‘06‘,b‘23‘])TypeError: sequence item 2: expected str instance, bytes found
>>> ‘,‘.join({‘dobi‘:‘dog‘, ‘polly‘:‘bird‘})
‘dobi,polly‘
>>> ‘,‘.join({‘dobi‘:‘dog‘, ‘polly‘:‘bird‘}.values())
‘dog,bird‘

2)str.partition(sep);
str.rpartition(sep)
——partition() 方法用来根据指定的分隔符将字符串进行分割。
如果字符串包含指定的分隔符,则返回一个3元的元组,第一个为分隔符左边的子串,第二个为分隔符本身,第三个为分隔符右边的子串。
== partition() 方法是在2.5版中新增的==

string.rpartition(str)
     ——类似于 partition()函数,不过是从右边开始查找.
     
>>> str=‘http://blog.csdn.net/anneqiqi/article/details/51725658‘
>>> str.partition(‘://‘)
(‘http‘, ‘://‘, ‘blog.csdn.net/anneqiqi/article/details/51725658‘) >>> ‘Anne,My best love‘.partition(‘love‘)(‘Anne,My best ‘, ‘love‘, ‘‘) >>> ‘Anne,My best love‘.partition(‘ll‘)(‘Anne,My best love‘, ‘‘, ‘‘) >>> ‘Anne,My best love‘.rpartition(‘love‘)(‘Anne,My best ‘, ‘love‘, ‘‘) >>> ‘Anne,My best love‘.rpartition(‘,‘)(‘Anne‘, ‘,‘, ‘My best love‘)

3)str.split(sep=None, maxsplit=-1);
str.rsplit(sep=None, maxsplit=-1)
——分隔字符串

>>> ‘1,2,3‘.split(‘,‘)[‘1‘, ‘2‘, ‘3‘]
>>> ‘1,2,3‘.rsplit(‘,‘)[‘1‘, ‘2‘, ‘3‘]
>>> ‘1,2,3‘.split(‘,‘, maxsplit=1)[‘1‘, ‘2,3‘]
>>> ‘1,2,3‘.rsplit(‘,‘, maxsplit=1)[‘1,2‘, ‘3‘]
>>> ‘1 2 3‘.split()[‘1‘, ‘2‘, ‘3‘]
>>> ‘1 2 3‘.rsplit()[‘1‘, ‘2‘, ‘3‘]
>>> ‘1 2 3‘.split(maxsplit=1)[‘1‘, ‘2 3‘]
>>> ‘1 2 3‘.rsplit(maxsplit=1)[‘1 2‘, ‘3‘]
>>> ‘   1   2   3   ‘.split()[‘1‘, ‘2‘, ‘3‘]
>>> ‘1,2,,3,‘.split(‘,‘)[‘1‘, ‘2‘, ‘‘, ‘3‘, ‘‘]
>>> ‘1,2,,3,‘.rsplit(‘,‘)[‘1‘, ‘2‘, ‘‘, ‘3‘, ‘‘]
>>> ‘‘.split()[]
>>> ‘‘.split(‘a‘)[‘‘]
>>> ‘bcd‘.split(‘a‘)[‘bcd‘]
>>> ‘bcd‘.split(None)[‘bcd‘]
>>> 
  • str.split(str="", num=string.count(str)).

    str = "Line1-abcdef \nLine2-abc \nLine4-abcd";
    str.split()
    [‘Line1-abcdef‘, ‘Line2-abc‘, ‘Line4-abcd‘]
    str.split(‘ ‘,1)
    [‘Line1-abcdef‘, ‘\nLine2-abc \nLine4-abcd‘]

    • str -- 分隔符,默认为空格。

    • num -- 分割次数。

4)str.splitlines([keepends])
——字符串以行界符为分隔符拆分为列表;当 keepends 为True,拆分后保留行界符,能被识别的行界符见官方文档。
5)string.splitlines(num=string.count(‘\n‘))
——按照行分隔,返回一个包含各行作为元素的列表,如果 num 指定则仅切片 num 个行.

字符串条件判断


1)str.endswith(suffix[, start[, end]]);
str.startswith(prefix[, start[, end]])
- suffix -- 该参数可以是一个字符串或者是一个元素。
- start -- 字符串中的开始位置。
- end -- 字符中结束位置。

>>> str=‘this is string example ... wow!!!‘

>>> suffix=‘wow!!‘

>>> str.endswith(suffix)
False

>>> suffix=‘wow!!!‘

>>> str.endswith(suffix)
True

>>> str.endswith(suffix,20)
True

>>> suffix=‘is‘

>>> str.endswith(suffix,2,4)
True

>>> str.endswith(suffix,2,6)
False
?
>>>

2)string.isalnum()

 ——如果 string 至少有一个字符并且所有字符都是字母或数字则返回 True,否则返回 False

3)string.isalpha()
——如果 string 至少有一个字符并且所有字符都是字母则返回 True,否则返回 False

4)string.isdecimal()
——如果 string 只包含十进制数字则返回 True 否则返回 False.
isdecimal()方法检查字符串是否只包含十进制字符。这种方法只存在于unicode对象。

5)string.isdigit()
——如果 string 只包含数字则返回 True 否则返回 False.

6)string.islower()
——如果 string 中包含至少一个区分大小写的字符,并且所有这些(区分大小写的)字符都是小写,则返回 True,否则返回 False

7)string.isnumeric()
——如果 string 中只包含数字字符,则返回 True,否则返回 False

8)string.isspace()
——如果 string 中只包含空格,则返回 True,否则返回 False.

9)string.istitle()
——如果 string 是标题化的(见 title())则返回 True,否则返回 False

10)string.isupper()
——以 str 为分隔符切片 string,如果 num有指定值,则仅分隔 num 个子字符串

11)string.startswith(obj, beg=0,end=len(string))
——检查字符串是否是以 obj 开头,是则返回 True,否则返回 False。如果beg 和 end 指定值,则在指定范围内检查.

Python3访问字符串

    Python不支持单字符类型,单字符在Python中也是作为一个字符串来使用;

    字符串切片截取;

空值

空值是Python里一个特殊的值,用None表示。None不能理解为0,因为0是有意义的,而None是一个特殊的空值。

最后,理解变量在计算机内存中的表示也非常重要。当我们写:

a = ‘ABC‘

时,Python解释器干了两件事情:

  1. 在内存中创建了一个‘ABC‘的字符串;

  2. 在内存中创建了一个名为a的变量,并把它指向‘ABC‘

也可以把一个变量a赋值给另一个变量b,这个操作实际上是把变量b指向变量a所指向的数据,例如下面的代码:

a = ‘ABC‘
b = a a = ‘XYZ‘
print(b)

最后一行打印出变量b的内容到底是‘ABC‘呢还是‘XYZ‘?如果从数学意义上理解,就会错误地得出ba相同,也应该是‘XYZ‘,但实际上b的值是‘ABC‘,让我们一行一行地执行代码,就可以看到到底发生了什么事:

执行a = ‘ABC‘,解释器创建了字符串‘ABC‘和变量a,并把a指向‘ABC‘

技术分享

执行b = a,解释器创建了变量b,并把b指向a指向的字符串‘ABC‘

技术分享

执行a = ‘XYZ‘,解释器创建了字符串‘XYZ‘,并把a的指向改为‘XYZ‘,但b并没有更改:

技术分享

所以,最后打印变量b的结果自然是‘ABC‘了。




字符编码

我们已经讲过了,字符串也是一种数据类型,但是,字符串比较特殊的是还有一个编码问题。

因为计算机只能处理数字,如果要处理文本,就必须先把文本转换为数字才能处理。最早的计算机在设计时采用8个比特(bit)作为一个字节(byte),所以,一个字节能表示的最大的整数就是255(二进制11111111=十进制255),如果要表示更大的整数,就必须用更多的字节。比如两个字节可以表示的最大整数是65535,4个字节可以表示的最大整数是4294967295。

由于计算机是美国人发明的,因此,最早只有127个字母被编码到计算机里,也就是大小写英文字母、数字和一些符号,这个编码表被称为ASCII编码,比如大写字母A的编码是65,小写字母z的编码是122。

但是要处理中文显然一个字节是不够的,至少需要两个字节,而且还不能和ASCII编码冲突,所以,中国制定了GB2312编码,用来把中文编进去。

你可以想得到的是,全世界有上百种语言,日本把日文编到Shift_JIS里,韩国把韩文编到Euc-kr里,各国有各国的标准,就会不可避免地出现冲突,结果就是,在多语言混合的文本中,显示出来会有乱码。

>>> fruit=‘banana‘
>>> letter=fruit[1] #从fruit中选择索引为1的字符并将他赋给
letter
>>> letter‘a‘>>>

除了数字,Python还可以操纵字符串,可以一几种不同的方式表达。他们可以包含在单引号(‘...’)或者("...")双引号中,其结果相同

>>> ‘apple‘‘apple‘
>>> ‘doesn\‘t‘  #可以用\’转义字符
"doesn‘t"
>>> "doesn‘t"   #或者用两个不一样的引号
"doesn‘t"
>>> ‘"Yes,"he said‘
‘"Yes,"he said‘
>>> "\"Yes,\"he said"
‘"Yes,"he said‘
>>> ‘"Isn\‘t," seh said.‘
‘"Isn\‘t," seh said.‘

在交互式解释器,输出字符串包含在引号和特殊字与反斜杠转义。虽然这时有所不同,从输入(包含引号可以改变),这两个字符串是一样的。如果字符串包含双引号和单引号,该字符串给括在双引号中,否则被括在单引号中。print() 函数生成一个更可读的输出。\可用于转义引号。

>>> ‘"Isn\‘t"she said.‘‘"Isn\‘t"she said.‘
>>> print(‘"Isn\‘t"she said.‘)
"Isn‘t"she said.
>>> >>> s=‘First line.\nSecond line.‘ #\n表示换行=
>>> s‘First line.\nSecond line.‘
>>> print(s)First line.Second line.
>>>

如果你不想被\前缀解释为特殊字符,你可以使用原始字符串之前的字符串前加一个 r ;

>>> print(‘C:\some\name‘)
C:\some
ame
>>> print(r‘C:\some\name‘) C:\some\name
>>>

字符串连接

1:字符串可以通过+或者*操作符连接;

>>> #重复3次‘un’之后,后面加上‘ium’
>>> 3*‘um‘+‘ium‘
‘umumumium‘
>>>

2:两个或多个字符串(封闭的引号隔开)相邻之间自动连接;

>>> ‘py‘‘thon‘ #中间留不留空格效果一样
‘python‘
>>>

注:这只适用于两个字符串,而不是用于变量或者表达式;

>>> prefix=‘py‘
>>> preix ‘thon‘
SyntaxError: invalid syntax
>>> (‘un‘*3)‘ium‘
SyntaxError: invalid syntax
>>>

3:如果你想连接两个变量,使用+操作符可以实现

>>> prefix=‘py‘
>>> prefix+‘thon‘
‘python‘
>>>

4:一下字符串有其有用,当你想要打破输入一个长字符串;

>>> text=(‘My name is Anne,This is My page,‘
‘Welcome to my house!‘)
>>> text‘My name is Anne,This is My page,Welcome to my house!‘
>>> 

字符串访问

1:字符串可以被索引(下标)访问;没有单独的字符类型,一个字符就是一个
字符串的大小;

>>> word=‘python‘
>>> word[0]     #在位置0,word的第一个字符
‘p‘
>>> word[5]
‘n‘
>>>

2:索引也有可能是负数,从右边开始计数;

>>> word[-1]
‘n‘
>>> word[-6]
‘p‘
>>>

注意:-0和0是一样的,负数索引从零开始;

字符串切片

>>> word[0:2]       #从零位置到2的字符

‘py‘

>>> word[2:5]
‘tho‘

>>>

注意:一开始总是被包括,最后总是被排除在外,这确保s[:i]+s[i:]总是等价于s

>>> word=‘python‘

>>> word[:2]+word[2:]
‘python‘

>>> word[:4]+word[4:]
‘python‘

>>> word[:8]+word[:8]
‘pythonpython‘

>>> word[:1]+word[1:]
‘python‘>>>

切片索引可以使用默认值,s[:i]省略第一个索引默认为零;s[i:]省略第二个索引默认被切片的字符串的大小。

试图使用太大的索引将导致一个错误。

>>> word[89]    #word只有6个字母Traceback (most recent call last):
  File "<pyshell#5>", line 1, in <module>
    word[89]IndexError: string index out of range
>>>

但是,此种情况下是可以使用切片的:

>>> word[2:89]
‘thon‘
>>>

上次已经说过Python字符串不能改变——他们是不可变的。因此,指定字符串中的索引位置导致一个错误。

>>> word[0]=‘J‘Traceback (most recent call last):
  File "<pyshell#7>", line 1, in <module>
    word[0]=‘J‘TypeError: ‘str‘ object does not support item assignment>>> word[2:]=‘py‘Traceback (most recent call last):
  File "<pyshell#8>", line 1, in <module>
    word[2:]=‘py‘TypeError: ‘str‘ object does not support item assignment>>> ‘j‘+word[1:]
‘jython‘
>>>

字符串处理是非常常用的技能,但 Python 内置字符串方法太多,常常遗忘,为了便于快速参考,特地依据 Python 3.5.1 给每个内置方法写了示例并进行了归类,便于大家索引。

PS: 可以点击概览内的绿色标题进入相应分类或者通过右侧边栏文章目录快速索引相应方法。

String Method 概览

字符串大小写转换

str.capitalize()
str.lower()
str.casefold()
str.swapcase()
str.title()
str.upper()

字符串格式输出

str.center(width[, fillchar])
str.ljust(width[, fillchar]);
str.rjust(width[, fillchar])
str.zfill(width)
str.expandtabs(tabsize=8)
str.format(^args, ^^kwargs)
str.format_map(mapping)

字符串搜索定位与替换

str.count(sub[, start[, end]])
str.find(sub[, start[, end]]); str.rfind(sub[, start[, end]])
str.index(sub[, start[, end]]); str.rindex(sub[, start[, end]])
str.replace(old, new[, count])
str.lstrip([chars]); str.rstrip([chars]); str.strip([chars])
static str.maketrans(x[, y[, z]]); str.translate(table)

字符串的联合与分割

str.join(iterable)
str.partition(sep);
str.rpartition(sep)
str.split(sep=None, maxsplit=-1);
str.rsplit(sep=None, maxsplit=-1)
str.splitlines([keepends])

字符串条件判断

str.endswith(suffix[, start[, end]]);
str.startswith(prefix[, start[, end]]) str.isalnum()
str.isalpha()
str.isdecimal();
str.isdigit();
str.isnumeric()
str.isidentifier()
str.islower()
str.isprintable()
str.isspace()
str.istitle()
str.isupper()

字符串编码

str.encode(encoding="utf-8", errors="strict")

大小写转换


1)str.capitalize()
——返回的字符串的首字母大写,其余小写。

>>> word.capitalize()‘Python‘>>> 

2)str.lower()
——把字符串改为小写的形式

>>> name="ANNE"
>>> name.lower()
‘anne‘
>>>

3)str.upper()
——把字符串改为大写的形式

>>> name="anne"
>>> name.upper()
‘ANNE‘
>>>

需要注意的是 s.upper().isupper() 不一定为 True。

4)str.casefold()
——将字符串转换成小写,Unicode编码中凡是有对应的小写形式的,都会转换;

>>> ‘FAFD‘.casefold()
‘fafd‘
>>> ‘徐XU‘.casefold()
‘徐xu‘
>>>

5)str.swapcase()
——对字符串字母的大小写进行反转。

>>> ‘dao‘.swapcase()
‘DAO‘
>>> ‘Daio‘.swapcase()
‘dAIO‘
>>>

但是需要注意的是:str.swapcase().swapcase()==str不一定为真

6)str.title()
——将字符串中每个“单词”首字母。其判断“单词”的依据则是基于空格和标点,所以应对英文撇好所有格或一些英文大写的简写时,会出错。
注意title和capitalize的区别;

>>> ‘hello world‘.capitalize()
‘Hello world‘
>>> ‘hello world‘.title()
‘Hello World‘
>>>

字符串格式输出


1)str.center(width[, fillchar])
——将字符串按照给定的宽度居中显示,可以给定特定的字符填充多余的长度,如果指定的长度小于字符串长度,则返回原字符串。

>>> ‘Anne‘.center(10)
‘   Anne   ‘
>>> ‘Anne‘.center(10,‘*‘)
‘***Anne***‘
>>> ‘Anne‘.center(5)
‘ Anne‘

2)str.ljust(width[, fillchar]);
str.rjust(width[, fillchar])
——返回指定长度的字符串,字符串内容居左(右)如果长度小于字符串长度,则返回原始字符串,默认填充为 ASCII 空格,可指定填充的字符串。

>>> ‘Anne‘.ljust(3)
‘Anne‘
>>> ‘Anne‘.ljust(5)
‘Anne ‘
>>> ‘Anne‘.ljust(3,‘~‘)
‘Anne‘
>>> ‘Anne‘.ljust(10,‘~‘)
‘Anne~~~~~~‘
>>>

3)str.zfill(width)
——用 ‘0‘ 填充字符串,并返回指定宽度的字符串。

>>> ‘77‘.zfill(5)
‘00077‘
>>> ‘-77‘.zfill(5)
‘-0077‘
>>> ‘qi‘.zfill(5)
‘000qi‘
>>> ‘--‘.zfill(5)
‘-000-‘
>>> ‘ ‘.zfill(5)
‘0000 ‘
>>> ‘  ‘.zfill(5)
‘000  ‘
>>> ‘‘.zfill()      #括号里面一定要添加数字 Traceback (most recent call last):  File "<pyshell#8>", line 1, in <module>    ‘‘.zfill()TypeError: zfill() takes exactly 1 argument (0 given) >>> ‘‘.zfill(5)
‘00000‘
>>> ‘qiqiq‘.zfill(5)
‘qiqiq‘
>>>

4)str.expandtabs(tabsize=8)
——用指定的空格替代横向制表符,使得相邻字符串之间的间距保持在指定的空格数以内。tab 符号默认的空格数是 8。
>>> tab = ‘1\t23\t456\t7890\t1112131415\t161718192021‘
>>> tab.expandtabs()
‘1 23 456 7890 1112131415 161718192021‘
>>> tab.expandtabs(4)
‘1 23 456 7890 1112131415 161718192021‘
>>>
5)str.format(^args, ^^kwargs)
——格式化字符串的语法比较繁多,官方文档已经有比较详细的 examples,我上一节也已经介绍了,这里就不冗余解释了;
6)str.format_map(mapping)
——类似 str.format(*args, **kwargs) ,不同的是 mapping 是一个字典对象。

>>> People = {‘name‘:‘john‘, ‘age‘:56}
>>> ‘My name is {name},i am {age} old‘.format_map(People)
‘My name is john,i am 56 old‘
>>>

字符串搜索定位与替换


1)str.count(sub[, start[, end]])
——返回指定字符在[指定位置的]str出现的次数

>>> text = ‘outer protective covering‘
>>> text.count(‘e‘)
4
>>> text.count(‘e‘, 5, 11)
1
>>> text.count(‘e‘, 5, 10)
0

2)str.find(sub[, start[, end]]); str.rfind(sub[, start[, end]])
——返回指定字符在[指定位置的]str出现的索引

>>> text = ‘outer protective covering‘
>>> text.find(‘er‘)
3
>>> text.find(‘er‘, 3)
3
>>> text.find(‘er‘, 4)
20
>>> text.find(‘er‘, 4, 21)      #找不到就会返回-1; -1
>>> text.rfind(‘er‘)
20
>>> text.lfind(‘er‘)        #没有这个方法 Traceback (most recent call last):  File "<pyshell#16>", line 1, in <module>    text.lfind(‘er‘)AttributeError: ‘str‘ object has no attribute ‘lfind‘>>> text.rfind(‘er‘, 20)
20
>>> text.rfind(‘er‘, 20, 21)        #找不到返回-1
-1
>>>

3)str.index(sub[, start[, end]]);
str.rindex(sub[, start[, end]])
——与 find() rfind() 类似,不同的是如果找不到,就会引发 ValueError。

>>> text
‘outer protective covering‘
>>> text.index(‘e‘)
3
>>> text.index(‘e‘,4)
10
>>> text.index(‘e‘,4,9)     #找不到就会引发ValueError错误 Traceback (most recent call last):  File "<pyshell#22>", line 1, in <module>    text.index(‘e‘,4,9)ValueError: substring not found

4)str.replace(old, new[, count])
——1)Python replace()方法把字符串中的old(旧字符替)换成new(新字符)。如果指定第三个参数max,则替换不超过max。
2)用法:str.replace(old,new[,max])
3)参数解释
●old---将被替换的子字符串
●new---新字符串,用于替换old子字符串
●max---可选字符串,替换不超过max次

此方法已经在字符串解说(上)中介绍过了。只给出如下实例,不做过多冗余;
>>> ‘Anne is very very good guy‘.replace(‘very‘,‘so‘)‘Anne is so so good guy‘>>> ‘Anne is very very good guy‘.replace(‘very‘,‘so‘,0)‘Anne is very very good guy‘>>> ‘Anne is very very good guy‘.replace(‘very‘,‘so‘,1)‘Anne is so very good guy‘>>> ‘Anne is very very good guy‘.replace(‘very‘,‘so‘,2)‘Anne is so so good guy‘>>> ‘Anne is very very good guy‘.replace(‘very‘,‘so‘,3)‘Anne is so so good guy‘>>> 

5)str.lstrip([chars]); #chars --指定截取的字符。
str.rstrip([chars]);
str.strip([chars]);
——Python lstrip() 方法用于截掉字符串左边的空格或指定字符。返回截掉字符串左边的空格或指定字符后生成的新字符串。

>>> ‘   Hello World  ‘.lstrip()
‘Hello World  ‘
>>> ‘777Hello World77‘.lstrip(‘7‘)
‘Hello World77‘
>>>    ——Python rstrip() 删除 string 字符串末尾的指定字符(默认为空格).返回删除 string 字符串末尾的指定字符后生成的新字符串。

>>> ‘   Hello World  ‘.rstrip()
‘   Hello World‘
>>> ‘777Hello World77‘.rstrip(‘7‘)
‘777Hell    ——Python strip() 方法用于移除字符串头尾指定的字符(默认为空格)。返回移除字符串头尾指定的字符生成的新字符串 >>> ‘   Hello World  ‘.strip() ‘Hello World‘ >>> ‘77Hello World77‘.strip(‘77‘) ‘Hello World‘ >>>

6)static str.maketrans(x[, y[, z]]);
str.translate(table)
——maketrans 是一个静态方法,用于生成一个对照表,以供 translate 使用。
如果 maketrans 仅一个参数,则该参数必须是一个字典,字典的 key 要么是一个 Unicode 编码(一个整数),要么是一个长度为 1 的字符串,字典的 value 则可以是任意字符串、None或者 Unicode 编码。

>>> a = ‘dobi‘
>>> ord(‘o‘)
111
>>> ord(‘a‘)
97
>>> hex(ord(‘狗‘))
‘0x72d7‘
>>> b = {‘d‘:‘dobi‘, 111:‘ is ‘, ‘b‘:97, ‘i‘:‘\u72d7\u72d7‘}
?>>> table = str.maketrans(b)
?>>> a.translate(table)
?‘dobi is a狗狗‘
>>>

也可以简单一点生成对照表:

  >>> a=‘dobi‘
  >>> b = {‘d‘:‘dobi‘, ‘o‘:‘ is ‘, ‘b‘:‘a‘, ‘i‘:‘dog‘} 
 
 >>> table=str.maketrans(b)  
 >>> a.translate(table)
  ‘dobi is adog

——如果 maketrans 有两个参数,则两个参数形成映射,且两个字符串必须是长度相等;如果有第三个参数,则第三个参数也必须是字符串,该字符串将自动映射到 None


字符串的联合与分割


1)str.join(iterable)
——用指定的字符串,连接元素为字符串的可迭代对象。
str.join(seq)——以 str 作为分隔符,将 seq 中所有的元素(的字符串表示)合并为一个新的字符串

>>> ‘-‘.join([‘2016‘,‘06‘,‘23‘])
‘2016-06-23‘

>>> ‘-‘.join([])
‘‘
>>> ‘-‘.join([None])
Traceback (most recent call last):  File "<pyshell#2>", line 1, in <module>    ‘-‘.join([None])TypeError: sequence item 0: expected str instance, NoneType found
>>> ‘-‘.join([‘‘])
‘‘
>>> ‘-‘.join([‘2016‘,‘06‘,b‘23‘])   #byte为非字符串
Traceback (most recent call last):  File "<pyshell#4>", line 1, in <module>    ‘-‘.join([‘2016‘,‘06‘,b‘23‘])TypeError: sequence item 2: expected str instance, bytes found
>>> ‘,‘.join({‘dobi‘:‘dog‘, ‘polly‘:‘bird‘})
‘dobi,polly‘
>>> ‘,‘.join({‘dobi‘:‘dog‘, ‘polly‘:‘bird‘}.values())
‘dog,bird‘

2)str.partition(sep);
str.rpartition(sep)
——partition() 方法用来根据指定的分隔符将字符串进行分割。
如果字符串包含指定的分隔符,则返回一个3元的元组,第一个为分隔符左边的子串,第二个为分隔符本身,第三个为分隔符右边的子串。
== partition() 方法是在2.5版中新增的==

string.rpartition(str)
     ——类似于 partition()函数,不过是从右边开始查找.
     
>>> str=‘http://blog.csdn.net/anneqiqi/article/details/51725658‘
>>> str.partition(‘://‘)
(‘http‘, ‘://‘, ‘blog.csdn.net/anneqiqi/article/details/51725658‘) >>> ‘Anne,My best love‘.partition(‘love‘)(‘Anne,My best ‘, ‘love‘, ‘‘) >>> ‘Anne,My best love‘.partition(‘ll‘)(‘Anne,My best love‘, ‘‘, ‘‘) >>> ‘Anne,My best love‘.rpartition(‘love‘)(‘Anne,My best ‘, ‘love‘, ‘‘) >>> ‘Anne,My best love‘.rpartition(‘,‘)(‘Anne‘, ‘,‘, ‘My best love‘)

3)str.split(sep=None, maxsplit=-1);
str.rsplit(sep=None, maxsplit=-1)
——分隔字符串

>>> ‘1,2,3‘.split(‘,‘)[‘1‘, ‘2‘, ‘3‘]
>>> ‘1,2,3‘.rsplit(‘,‘)[‘1‘, ‘2‘, ‘3‘]
>>> ‘1,2,3‘.split(‘,‘, maxsplit=1)[‘1‘, ‘2,3‘]
>>> ‘1,2,3‘.rsplit(‘,‘, maxsplit=1)[‘1,2‘, ‘3‘]
>>> ‘1 2 3‘.split()[‘1‘, ‘2‘, ‘3‘]
>>> ‘1 2 3‘.rsplit()[‘1‘, ‘2‘, ‘3‘]
>>> ‘1 2 3‘.split(maxsplit=1)[‘1‘, ‘2 3‘]
>>> ‘1 2 3‘.rsplit(maxsplit=1)[‘1 2‘, ‘3‘]
>>> ‘   1   2   3   ‘.split()[‘1‘, ‘2‘, ‘3‘]
>>> ‘1,2,,3,‘.split(‘,‘)[‘1‘, ‘2‘, ‘‘, ‘3‘, ‘‘]
>>> ‘1,2,,3,‘.rsplit(‘,‘)[‘1‘, ‘2‘, ‘‘, ‘3‘, ‘‘]
>>> ‘‘.split()[]
>>> ‘‘.split(‘a‘)[‘‘]
>>> ‘bcd‘.split(‘a‘)[‘bcd‘]
>>> ‘bcd‘.split(None)[‘bcd‘]
>>> 
  • str.split(str="", num=string.count(str)).

    str = "Line1-abcdef \nLine2-abc \nLine4-abcd";
    str.split()
    [‘Line1-abcdef‘, ‘Line2-abc‘, ‘Line4-abcd‘]
    str.split(‘ ‘,1)
    [‘Line1-abcdef‘, ‘\nLine2-abc \nLine4-abcd‘]

    • str -- 分隔符,默认为空格。

    • num -- 分割次数。

4)str.splitlines([keepends])
——字符串以行界符为分隔符拆分为列表;当 keepends 为True,拆分后保留行界符,能被识别的行界符见官方文档。
5)string.splitlines(num=string.count(‘\n‘))
——按照行分隔,返回一个包含各行作为元素的列表,如果 num 指定则仅切片 num 个行.

字符串条件判断


1)str.endswith(suffix[, start[, end]]);
str.startswith(prefix[, start[, end]])
- suffix -- 该参数可以是一个字符串或者是一个元素。
- start -- 字符串中的开始位置。
- end -- 字符中结束位置。

>>> str=‘this is string example ... wow!!!‘

>>> suffix=‘wow!!‘

>>> str.endswith(suffix)
False

>>> suffix=‘wow!!!‘

>>> str.endswith(suffix)
True

>>> str.endswith(suffix,20)
True

>>> suffix=‘is‘

>>> str.endswith(suffix,2,4)
True

>>> str.endswith(suffix,2,6)
False
?
>>>

2)string.isalnum()

 ——如果 string 至少有一个字符并且所有字符都是字母或数字则返回 True,否则返回 False

3)string.isalpha()
——如果 string 至少有一个字符并且所有字符都是字母则返回 True,否则返回 False

4)string.isdecimal()
——如果 string 只包含十进制数字则返回 True 否则返回 False.
isdecimal()方法检查字符串是否只包含十进制字符。这种方法只存在于unicode对象。

5)string.isdigit()
——如果 string 只包含数字则返回 True 否则返回 False.

6)string.islower()
——如果 string 中包含至少一个区分大小写的字符,并且所有这些(区分大小写的)字符都是小写,则返回 True,否则返回 False

7)string.isnumeric()
——如果 string 中只包含数字字符,则返回 True,否则返回 False

8)string.isspace()
——如果 string 中只包含空格,则返回 True,否则返回 False.

9)string.istitle()
——如果 string 是标题化的(见 title())则返回 True,否则返回 False

10)string.isupper()
——以 str 为分隔符切片 string,如果 num有指定值,则仅分隔 num 个子字符串

11)string.startswith(obj, beg=0,end=len(string))
——检查字符串是否是以 obj 开头,是则返回 True,否则返回 False。如果beg 和 end 指定值,则在指定范围内检查.

Python3字符串各种内置函数详解

标签:

原文地址:http://blog.csdn.net/anneqiqi/article/details/51742961

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!