跟c和java等语言不一样,python里是没有字符这个类型的,所以对于python来说,单引号和双引号是一样的(如:’c’和”c”是一样的,代表一个字符串),如果字符串中包含换行符等特殊符号时,可以使用三引号(”’test \n test”’或者”””test \n test”””)。python中字符串是不可变类型,只能通过新建一个字符串去改变一个字符串的元素,可以通过id(string)检查字符串对象的身份。
1. 字符串操作符
在python中字符串也是一个序列,所以支持序列类型的基本操作。
1.1 成员关系操作(in ,not in)
判断一个字符或者字符串是否属于这个字符串 obj [not] in sequence,返回值位True或False
1
2
3
4
5
6
7
8
|
>>>
'a'
in
'abc'
True
>>>
'a'
not
in
'abc'
False
>>>
'ab'
in
'abc'
True
>>>
'e'
in
'abc'
False
|
1.2 连接操作(+)
该操作把两个字符串连接,创建一个新的字符串
1
2
|
>>>
'a'
+
'b'
+
'c'
+
'd'
'abcd'
|
连接操作的性能不是很好,每次连接都会创建一个新的字符串对象,可以用格式化操作符或者join函数取代。
1
2
3
4
|
>>>
'%s%s%s%s'
%
(
'a'
,
'b'
,
'c'
,
'd'
)
'abcd'
>>> '
'.join(['
a
','
b
','
c
','
d'])
'abcd'
|
ps:str.join(list),使用str作为分隔符,把list里的元素连接成一个字符串。如:’*’.join([‘a’,’b’,’c’])得到’a*b*c’
1.3 重复操作 (*)
1
2
|
>>>
'a'
*
4
'aaaa'
|
1.4 切片操作 ([],[:],[::])
因为序列类型是元素被顺序放置的一种数据结构,因此可以通过下标来获取某一个元素或者指定下标范围来获取一组元素。假设字符串的长度为len,则index的范围是0到len-1.
1
2
3
4
5
6
7
8
9
|
>>> s
=
'abcd'
>>> s[
0
]
'a'
>>> s[:
1
]
'a'
>>> s[
1
:
2
]
'b'
>>> s[::]
'abcd'
|
另外,也可以使用负索引,index范围是-len到-1,正索引和负索引的区别是:正索引以序列的开始为起点,负索引以序列的结束为起点。
1
2
3
4
5
6
|
>>> s[
-
1
]
'd'
>>> s[
-
len
(s)]
'a'
>>> s[
-
len
(s):
-
1
]
'abc'
|
ps:切片的操作很灵活,开始和结束的索引值可以超过字符串的长度
1
2
|
>>> s[
-
100
:
100
]
'abcd'
|
1.5 格式化操作(%)
python的字符串格式化操作跟C语言printf()函数的字符串格式化很类似,并且支持所有的printf()格式化操作。
%c | 转换成字符(ASCII 码值,或者长度为一的字符串) |
%r | 优先用 repr()函数进行字符串转换 |
%s | 优先用 str()函数进行字符串转换 |
%d / %i | 转成有符号十进制数 |
%ub | 转成无符号十进制数 |
%ob | 转成无符号八进制数 |
%xb/%Xb | (Unsigned)转成无符号十六进制数(x/X 代表转换后的十六进制字符的大小写) |
%e/%E | 转成科学计数法(e/E 控制输出 e/E) |
%f/%F | 转成浮点数(小数部分自然截断) |
%g/%G | %e 和%f/%E 和%F 的简写 |
%% | 输出% |
ps:repr()和str()的区别可以自己google一下,repr()的目标是生成一个传给eval()的字符串,是给解释器读取的,所以打印的信息不是很友好;str()的目标是生成可打印字符串,适合人阅读的,因此更友好。
1
2
3
4
|
>>>
'%r'
%
(
'alexzhou'
)
"'alexzhou'"
>>>
'%s'
%
(
'alexzhou'
)
'alexzhou'
|
python格式化支持两种格式的输入参数:元组(常用)和字典。
1
2
3
4
|
>>>
'%s%d'
%
(
'alexzhou'
,
23
)
'alexzhou23'
>>>
'%(name)s%(age)d'
%
{
'name'
:
'alexzhou'
,
'age'
:
23
}
'alexzhou23'
|
2. 常用内建函数
2.1 cmp() 根据字符串的ASCII码值进行比较
1
2
3
4
5
6
7
8
|
>>> s1
=
'abc'
>>> s2
=
'xyz'
>>>
cmp
(s1,s2)
-
1
>>>
cmp
(s1,s1)
0
>>>
cmp
(s2,s1)
1
|
2.2 len() 返回字符串的字符数
1
2
3
|
>>> s1
=
'abcd'
>>>
len
(s1)
4
|
2.3 enumerate() 遍历序列的同时得到索引
1
2
3
4
5
6
7
8
9
10
11
12
|
>>> s
=
'alexzhou'
>>>
for
i,t
in
enumerate
(s):
...
print
i,t
...
0
a
1
l
2
e
3
x
4
z
5
h
6
o
7
u
|
2.4 raw_input() 使用给定字符串提示用户输入并将这个输入返回
1
2
3
|
>>>
raw_input
(
'name:'
)
name:alexzhou
'alexzhou'
|
2.5 字符串内建函数
(1)string.capitalize() 把字符串的第一个字符大写
1
2
|
>>> s.capitalize()
'Alexzhou'
|
(2)string.count(str,beg=0,end=len(string))
返回beg和end范围内str在string里出现的次数
1
2
3
4
|
>>> s.count(
'ex'
)
1
>>> s.count(
'ex'
,
3
)
0
|
(3)string.decode(encoding=’UTF-8′,errors=’strict’)和string.encode(encoding=’UTF-8′,errors=’strict’)
以encoding指定的编码格式解码和编码字符串
1
2
3
4
5
|
>>> s
=
u
'alexzhou'
>>> s.encode(
'utf-8'
)
'alexzhou'
>>> s.decode(
'utf-8'
)
u
'alexzhou'
|
(4)string.endswith(obj,beg=0,end=len(string)),string.startswith(obj,beg=0,end=len(string))
检查在beg和end范围内字符串是否以obj结束或开头
1
2
3
4
5
6
7
8
9
10
11
|
>>> s
=
u
'alexzhou'
>>> s.endswith(
'ou'
)
True
>>> s.endswith(
'ou'
,
2
)
True
>>> s.endswith(
'ou'
,
2
,
4
)
False
>>> s.startswith(
'alex'
)
True
>>> s.startswith(
'alex'
,
2
)
False
|
1
|
|
(5) string.find(str,beg=0,end=len(string)) 检查在beg和end范围内,str是否出现在string中,如果是则返回开始的索引,否则返回-1
1
2
3
4
|
>>> s.find(
'ou'
)
6
>>> s.find(
'ddf'
)
-
1
|
(6)string.index(str,beg=0,end=len(string))
检查str是否在string中,如果不在,则会报ValueError
1
2
3
4
|
>>> s.index(
'ddf'
)
Traceback (most recent call last):
File
"<stdin>"
, line
1
,
in
<module>
ValueError: substring
not
found
|
(7)string.join(seq)
以string作为分隔符,将seq中的所有元素合并为一个新的字符串
1
2
3
|
>>> s
=
u
'alexzhou'
>>> u
'*'
.join(s)
u
'a*l*e*x*z*h*o*u'
|
(8)string.strip(),string.lstrip(),string.rstrip()
截掉字符串左右两边的空格,截掉字符串左边的空格,截掉字符串右边的空格
1
2
3
4
5
6
7
8
9
|
>>> s
=
u
' alexzhou '
>>> s.strip()
u
'alexzhou'
>>> s
=
u
' alexzhou '
>>> s.lstrip()
u
'alexzhou '
>>> s
=
u
' alexzhou '
>>> s.rstrip()
u
' alexzhou'
|
(9)string.replace(str1,str2,num=string.count(str1))
把字符串中str1替换成str2,替换num次
1
2
3
4
5
6
|
>>> s
=
u
'111111'
>>> s.replace(
'1'
,
'2'
)
u
'222222'
>>> s
=
u
'111111'
>>> s.replace(
'1'
,
'2'
,
3
)
u
'222111'
|
(10)string.split(str,num=string.count(str))
以str为分隔符切片字符串,分隔num个子字符串
1
2
3
4
5
6
|
>>> s
=
u
'1*2*3*4'
>>> s.split(
'*'
)
[u
'1'
, u
'2'
, u
'3'
, u
'4'
]
>>> s
=
u
'1*2*3*4'
>>> s.split(
'*'
,
2
)
[u
'1'
, u
'2'
, u
'3*4'
]
|
3. 编码解码
python包含两种字符串:unicode字符串和一般字符串str,通过在字符串前加一个‘u’前缀的方式申明unicode字符串或者使用unicode(str,’utf-8′)的方式。basestring是unicode和str的父类,可以使用isinstance(obj, basestring) 来判断obj是否为一个字符串。
python通过encode()和decode()进行编码和解码,可以使用print打印一般字符串str和unicode字符串,print函数能够正确的解码和输出字符串。
1
2
3
4
5
6
7
8
9
10
11
|
>>> s
=
u
'alex周'
>>> s
u
'alex\u5468'
>>> s
=
s.encode(
'utf-8'
)
>>> s
'alex\xe5\x91\xa8'
>>> s
=
s.decode(
'utf-8'
)
>>> s
u
'alex\u5468'
>>>
print
s
alex周
|
unicode字符串中,默认一个中文占一个字符;编码格式为utf-8时,一个中文占3个字符;编码格式是gbk时,一个中文占2个字符。所以在检测字符串长度时,需注意。
1
2
3
4
5
6
7
8
9
10
11
12
13
|
>>> s
=
u
'周'
>>>
len
(s)
1
>>> s
=
s.encode(
'utf-8'
)
>>>
len
(s)
3
>>> s
=
s.decode(
'utf-8'
)
>>> s
=
s.encode(
'gbk'
)
>>>
len
(s)
2
>>> s
=
s.decode(
'gbk'
)
>>>
len
(s)
1
|
在实际应用开发中,遵守以下规则可以有效避免编码引起的bug:
- 程序中出现字符串时,需加上前缀‘u’
- 尽量用unicode()代替str()
- 只在写入文件或者数据库或处理网络数据时,才调用encode(),只有需要把数据读取回来时才调用decode(),编解码格式需统一
- 在py文件的开头加上:
123import
sys
reload
(sys)
sys.setdefaultencoding(
'utf-8'
)