字符串是 Python 中最常用的数据类型。我们可以使用引号(‘或”)来创建字符串。

  • 字符串字面量
  • 字符串操作
  • 字符串格式化
  • 字符串转换
  • 模式匹配(正则表达式)介绍

字面量

python 中单引号和双引号是一样的

In[1]:  
'span""m', "It's"
执行结果:
可以使用 '''""" 创建字符串
In[2]:  
'''aaaa''', """bbbb"""
执行结果:
带有转义字符的字符串,会将 \ 看做转义标识
In[3]:  
"a\tb\nc\0m"
执行结果:
原始字符串,以 r 开头并不会将 \ 看做转义标识
In[4]:  
r"a\b\c"  #
执行结果:
bytes 字符串,,以 b 开头
In[5]:  
b'sp\x01am'
执行结果:
Unicode 字符串,以 uU 开头
In[6]:  
u'eggs\u0020spam'
执行结果:
多行字符串
In[7]:  
s = """今天天气正好,
        我们去打球吧。
这是个好主意"""

s
执行结果:
In[8]:  
print(s)
执行结果:
In[9]:  
print('''aaaa
bbbb
     ddddd
    
ccccc''')
执行结果:

转义特殊字符串

在需要在字符中使用特殊字符时,python用反斜杠()转义字符。如下表:

转义字符 描述 示例
(在行尾时) 续行符
\n 换行
\ 反斜杠符号
\’ 单引号
\” 双引号
\a 响铃
\b 退格(Backspace)
\f 换页
\r 回车
\t 横向制表符
\v 纵向制表符
\x 十六进制数,yy代表的字符,例如:\x0a代表换行
\o 八进制数,yy代表的字符,例如:\o12代表换行
\0
\u 16位 Unicode 字符
\U 32位 Unicode 字符

原始字符串抑制转义

In[10]:  
s = 'a\nb\tc'
s
执行结果:
In[11]:  
print(s)
执行结果:
In[12]:  
len(s)
执行结果:
In[13]:  
'\0'
执行结果:
In[14]:  
len(r'a\nb\tc'), len('a\nb\tc')
执行结果:

字符串运算符

下表实例变量a值为字符串 “Hello”,b变量值为 “Python”:

操作符 描述 实例
+ 字符串连接 a + b 输出结果: HelloPython
* 重复输出字符串 a*2 输出结果:HelloHello
[] 通过索引获取字符串中字符 a[1] 输出结果 e
[ : ] 截取字符串中的一部分 a[1:4] 输出结果 ell
in 成员运算符 - 如果字符串中包含给定的字符返回 True ‘H’ in a 输出结果 1
not in 成员运算符 - 如果字符串中不包含给定的字符返回 True ’M’ not in a 输出结果 1
% 格式字符串 请看下一节内容。
In[15]:  
'abc' + 'def'
执行结果:
In[16]:  
'Ni' * 4
执行结果:
In[17]:  
print('-' * 80)
执行结果:
In[18]:  
myjob = "hacker"
for c in myjob:
    print(c, end=' ')
执行结果:
判断是否子串
In[19]:  
'k' in myjob
执行结果:
In[20]:  
'z' in myjob
执行结果:
In[21]:  
'spam' in 'abcspamdef'
执行结果:

索引和切割

S[i]: 抽取第 i 个字符

S[i:j]: 抽取索引为 i 到 j 的子串(包含 i 不包含 j)

S[i:]: 抽取索引为 i 之后的子串(包含 i)

S[:j]: 抽取索引为 j 之前的子串(不包含 j)

S[:]: 抽取整个字符串

S[i:j:k]: 抽取索引为 i 到 j 的子串(包含 i 不包含 j),步长为 k

S[::k]: 抽取整个字符串,步长为 k

S[::-1]: 反向抽取整个字符串

In[22]:  
S = 'spam'
S[0], S[-2]
执行结果:
In[23]:  
S[1:3], S[1:], S[:-1]
执行结果:
In[24]:  
S[0:4:2], S[::2], S[::-1]
执行结果:

字符串不可改变性

任何操作都不能改变原始字符串对象本身,都是产生新的字符串对象。当我们用变量时,会有一种改变字符串对象的错觉,这时其实是将变量指向了一个新的字符串对象。

In[25]:  
S = 'spam'
S[0] = 'x'
执行结果:
In[26]:  
S = S + 'SPAM!'  # 并没有改变原来的 'spam' 字符串对象,而是产生了一个新的字符串对象,并将变量 S 指向新对象
S
执行结果:
In[27]:  
S.replace('am', 'xxxx'), S  # 字符串的任何操作都不能改变源字符串对象
执行结果:
更多例子。注意这里的 spameggs 在内存中存储是不一样的,感兴趣的可以 google 一下。
In[28]:  
B = b'spam'
S = 'eggs'
type(B), type(S)
执行结果:
In[29]:  
B, S
执行结果:
In[30]:  
B[0], S[0]
执行结果:
In[31]:  
B[1:], S[1:]
执行结果:
In[32]:  
list(B), list(S)
执行结果:

字符串转换

数字转换

和其他动态类型语言不同,python 中字符串对象和数值对象是不能直接做运算的,必须进行显示转换。这是 python 和其他动态类型语言不同的地方,它的类型动态性只是表现在变量上面,对于对象本身必须是特定类型,并且是强类型的。对于变量和对象的关系请看前面的文章。

以下是一些实例:

In[33]:  
'42' + 1
执行结果:
In[34]:  
int('42'), str(42)
执行结果:
In[35]:  
repr(42)
执行结果:
In[36]:  
print(str('spam'), repr('spam'))
执行结果:

这里我们使用到了 strrepr 两个字符串函数,发现他们返回的东西几乎一样,其实他们是有差别的:

  • str() 的输出追求可读性,输出格式要便于理解,适合用于输出内容到用户终端。
  • repr() 的输出追求明确性,除了对象内容,还需要展示出对象的数据类型信息,适合开发和调试阶段使用。

有兴趣的可以使用 help 方法查看两者的区别。

以下是更多实例:

In[37]:  
int("42") + 1
执行结果:
In[38]:  
"42" + str(1)
执行结果:
In[39]:  
"1.234E-10", float("1.234E-10")
执行结果:
In[40]:  
B = '1101'
I = 0
while B!='':
    I = I*2 + (ord(B[0]) - ord('0'))
    B = B[1:]
I
执行结果:
In[41]:  
int('1101', 2), bin(13)
执行结果:

字符编码转换

对于单个字符可以使用 ord() 函数获取他的 ASCII 码值,一个 ASCII 码值使用 chr() 得到对于的字符。

In[42]:  
ord('s'), chr(115)
执行结果:
将字符转换成 ASCII 码过后,可以进行算数运算。但是直接使用字符做算数运算会报错,这里和 C 语言是不一样的。
In[43]:  
chr(ord('5')+1)
执行结果:
In[44]:  
ord('5') - ord('0')
执行结果:
In[45]:  
'5' - '0'
执行结果:

字符串方法调用

使用 dir("") 查看字符串类型有哪些支持的内置方法。每个方法的具体使用方式再使用 help() 查看。这里只列举部分方法使用

In[46]:  
# 字符串长度
len('abc')
执行结果:
In[47]:  
# 分隔字符串
'a,b,c'.split(',')
执行结果:
In[48]:  
# 字符串拼接
'>'.join(['a','b','c'])
执行结果:

字符串格式化

  1. 格式化表达式:’…%s…’ %(values)
  2. 格式化方法调用:’…{}…‘.format(values)

格式化符号

符 号 描述
%c 格式化字符及其ASCII码
%s 格式化字符串
%r 和 s 类似,但是使用 repr 输出
%d 格式化整数
%i 格式化整数
%u 格式化无符号整型
%o 格式化无符号八进制数
%x 格式化无符号十六进制数
%X 格式化无符号十六进制数(大写)
%f 格式化浮点数字,可指定小数点后的精度
%F 和 f 类似,但是字母大写
%e 用科学计数法格式化浮点数
%E 作用同%e,用科学计数法格式化浮点数
%g %f和%e的简写
%G %f 和 %E 的简写
%p 用十六进制数格式化变量的地址
%% 输出 %

基础格式化语法

%[(keyname)][flags][width][.precision]typecode

高级格式化语法

{fieldname component !conversionflag :formatspec}

formatspec: [[fill]align][sign][#][0][width][,][.precision][typecode]

格式化表达式

以下是一些实例

In[49]:  
x = 1234
'integers: ...%d...%-6d...%06d' % (x,x,x)
执行结果:
In[50]:  
x = 1.23456789
'%e | %f |%g' %(x,x,x)
执行结果:
In[51]:  
'%E' % x
执行结果:
更多格式化类型使用,请自行实践
In[52]:  
'%s' % x, str(x)
执行结果:
In[53]:  
# 基于字典的格式化

'a=%(a)d; b=%(bb)s' % {'a': 1, 'bb':'bbbb'}
执行结果:
vars() 函数返回所有的变量
In[54]:  
'%(x)s or %(S)s' % vars()
执行结果:

格式化方法

In[55]:  
template = '{0}, {1}, {2}'
template.format('spam', 'orange', 'apple')
执行结果:
In[56]:  
template = '{}, {}, {}'
template.format('spam', 'orange', 'apple')
执行结果:
In[57]:  
template = '{a}, {b}, {c}'
template.format(a='spam', c='orange', b='apple')
执行结果:
In[58]:  
template = '{a}, {b}, {0}'
template.format('spam', a='orange', b='apple')
执行结果:
添加关键字、属性和偏移量
In[59]:  
import sys
'My {1[kind]} runs {0.platform}'.format(sys, {'kind': 'laptop'})
执行结果:
In[60]:  
'My {map[kind]} runs {sys.platform}'.format(sys=sys, map={'kind': 'laptop'})
执行结果:
高级格式化
In[61]:  
'{:,d}'.format(9999999999)
执行结果:

bytearray 操作

对于 bytearray 这里列举一些使用的实例,不做深入介绍。

In[62]:  
S = 'spam'
# C = bytearray(S)  # 此语句在2.6+正常,但是在 3.X 中会语法错误
C = bytearray(S, 'latin1') 
C
执行结果:
In[63]:  
C = bytearray(b'spam')
C
执行结果:
In[64]:  
# bytearray 可以修改
C[0] = 10
In[65]:  
# 但是修改必须是整数,不能是字符
C[0] = '1'
执行结果:
In[66]:  
C[0] = ord('1')
C[1] = b'Y'[0]
C
执行结果:
In[67]:  
C
执行结果:

模式匹配

模式匹配也叫正则表达式,也是字符串处理的一种方式,由于其强大功能,在实际项目中被普遍使用。现在不论是什么语言都有提供模式匹配的功能,并且在正则表达式的功能和语法上都打通大同小异。由于其语言的独立性和重要性后面会单独讲解,这里为了字符串操作的完整性做简单的实例展示,不解释。 查找匹配

In[68]:  
import re

s='123abc456eabc789'
print(re.findall(r'abc',s))

s = 'I have a dog , I have a cat'
print(re.findall( r'I have a (?:dog|cat)' , s ))
执行结果:
使用compile加速
In[69]:  
s='111,222,aaa,bbb,555,ccc333,444ddd'
rule=r'\b\d+\b'
compiled_rule=re.compile(rule)
compiled_rule.findall(s)
执行结果:
匹配数字开头
In[71]:  
s='123 456/n789 012/n345 678'
rc=re.compile(r'^\d+') 
rc.findall(s)
执行结果:

小结

一篇文章不可能把字符串的方方面面都包括进来,比如字符串在 python 的存储、不同字符集的转行等。同时刚开始我们也不能用到所有的这些知识内容,所以在刚开始重点应该放在实际编码操作和整体知识体系的建立上,等熟练了或后面遇到相关问题了,在深入研究某块内容。希望对大家能有所帮助。