初识字符串

字符串就是一串字符,有短字符串(单行字符串)和长字符串(多行字符串)两种书写形式

与 C 不同,在 Python 中没有单个字符的类型,单个字符也按字符串处理

短字符串(单行字符串)

简单地使用引号括起来,单引号和双引号均可

1
2
"This is a string"
'This is also a string'

这种灵活性运允许你在字符串中包含引号和撇号,只要确保不与首尾两端的引号冲突

1
2
3
'I told my friend,"Python is my favorite language!"'
"The language 'Python' is name after Monty Python, not the snake."
"One of Python's strengths is its fiverse and supportive community."

Tip:续行符(反斜杠\)在字符串中也可以使用,故短字符串也可以写成多行

长字符串(多行字符串)

之前介绍 Python 多行注释时提到使用三个引号(单引号、双引号都行)来包含多行注释内容,这其实是长字符串的写法

只是由于在长字符串中可以放置任何内容,如果所定义的长字符串没有赋值给任何变量,那么这个字符串就相当于被解释器忽略了,也就相当于注释掉了

实际上,使用三个引号括起来的长字符串完全可以赋值给变量

1
2
3
4
s = '''"Let's go fishing", said Mary.
"OK, Let's go", said her brother.
they walked to a lake'''
print(s)

当程序中有大段文本内容要定义成字符串时,优先推荐使用长字符串形式,因为这种形式非常强大,可以让字符串中包含任何内容,既可包含单引号,也可包含双引号

Tip:长字符串也允许被写在一行里

转义字符

Python 中的转义字符大体与 C 中的相同

转义字符 描述
\(在行尾时) 续行符
\\ 反斜杠符号
\' 单引号
\" 双引号
\a 响铃
\b 退格
\n 换行
\v 纵向制表符
\t 横向制表符
\r 回车,将光标移到本行开头
\f 换页
\yyy 八进制数,y 代表 0~7 的字符,例如:\012 代表换行。
\xyy 十六进制数,以 \x 开头,y 代表的字符,例如:\x0a 代表换行

原始字符串

上述两种字符串默认都是启用转义的,这也会带来一些很麻烦的情况

比如打印一条 Windows 的路径 D:\study\python\tuple,其中的反斜杠需要写两次

1
print("D:\\study\\python\\tuple")

这很烦人,此时可借助于原始字符串来解决这个问题

原始字符串以rR开头,这样字符串中就不会把反斜杠当成特殊字符

1
print(r"D:\study\python\tuple")

但是,原始字符串在处理同时包含两种引号的字符串时会遇到麻烦,例如打印这个句子:"Let's go", said Charlie

正常情况下的两个版本:

1
2
print('"Let\'s go", said Charlie')  # "Let's go", said Charlie
print("\"Let's go\", said Charlie") # "Let's go", said Charlie

但在使用原始字符串时,就没有能正常输出的方案:

1
2
3
4
print(r'"Let's go", said Charlie')   # 语法错误
print(r""Let's go", said Charlie") # 语法错误
print(r'"Let\'s go", said Charlie') # "Let\'s go", said Charlie
print(r"\"Let's go\", said Charlie") # \"Let's go\", said Charlie

一种解决方案是将引号单独写,再拼接到一起,但这未免过于麻烦了

另外一种是使用长字符串

1
print('''"Let's go", said Charlie''') #"Let's go", said Charlie

原始字符串+长字符串的写法也是被允许的,这样你就不需要管转义,也不需要管引号了!

1
print(r'''"Let's go", said Charlie \n\t\\''') #"Let's go", said Charlie \n\t\\

访问字符串中的值

索引字符串

使用 变量[下标] 来索引单个字符

下标可以从前往后数(头是 0 ,往后递增)也可以从后往前数(尾是 -1 ,往前递减,倒数第 x 个就是 -x

s = "Hello" ‘H’ ‘e’ ‘l’ ‘l’ ‘o’
从前往后数 0 1 2 3 4
从后往前数 -5 -4 -3 -2 -1

注意: 不要以为能用索引的方法编辑字符串

样例:

1
2
3
4
5
6
s = "Hello"
print(s[0]) # H
print(s[1]) # e
print(s[2]) # l
print(s[3]) # l
print(s[4]) # o

截取字符串

使用 变量[起始位置:终止位置:步长] 来截取部分字符串(切片)

注意:

  • 左闭右开规则(顾头不顾尾)
  • 某个位置不指定的时候默认取最后或最前
  • 步长可选,默认为 1
  • 切片的时候起始位置和终止位置都超出的时候不会进行报错,但是索引会报错

样例:

1
2
3
4
5
6
7
8
s = "Hello"
print(s[0:5]) # Hello
print(s[:5]) # Hello
print(s[0:]) # Hello
print(s[:]) # Hello
print(s[1:4]) # ell
print(s[1:4:2]) # el
print(s[-1::-1]) #olleH

拼接字符串

字符串与字符串拼接

使用+来拼接

1
2
3
4
s1 = "Hello"
s2 = "World"
s3 = s1 + s2
print(s3) # HelloWorld

数字与字符串拼接

数字不能直接与字符串拼接,必须先用 str()repr() 转换为字符串

1
2
3
4
a = 123
b = "456"
c = str(a) + b
print(c) # 123456

二者的不同是:str() 用于将值转化为适于人阅读的形式,而 repr() 转化为供解释器读取的形式

格式化字符串

%格式符

与 C 中的 printf() 十分类似

1
2
>>> "今天是%d月%d日,天气%s" % (3, 5, "阴")
'今天是3月5日,天气阴'

详细信息请看Python格式化字符串(格式化输出)

.format() 方法

1
2
3
4
5
6
7
8
9
10
11
name = "jerry{},{},{}"
print(name.format(1,2,3)) #按照位置顺序进行填充
输出 jerry1,2,3

name = "jerry{2},{0},{1}"
print(name.format("a","b","c")) #按照索引值进行填充
输出 jerryc,a,b

name = "jerry{a},{b},{c}"
print(name.format(a=1,c=2,b=3)) #按照关键字进行填充
输出 jerry1,3,2

f-string

Python3.6 后引入了 f-string ,称之为字面量格式化字符串

f-string 格式化字符串以 f 开头,后面跟着字符串,字符串中的表达式用大括号 {} 包起来,它会将变量或表达式计算后的值替换进去,不用再去判断使用 %s,还是 %d

引用菜鸟教程中的例子:

1
2
3
4
5
6
7
8
9
>>> name = 'Runoob'
>>> f'Hello {name}' # 替换变量
'Hello Runoob'
>>> f'{1+2}' # 使用表达式
'3'

>>> w = {'name': 'Runoob', 'url': 'www.runoob.com'}
>>> f'{w["name"]}: {w["url"]}'
'Runoob: www.runoob.com'

字符串运算符

下表实例变量 a 值为字符串 "Hello"b 变量值为 "Python"

操作符 描述 实例
+ 字符串连接 a + b 输出结果: HelloPython
* 重复输出字符串 a*2 输出结果:HelloHello
[] 通过索引获取字符串中字符 a[1] 输出结果 e
[ : ] 截取字符串 a[1:4] 输出结果 ell
in 成员运算符 - 如果字符串中包含给定的字符返回 True 'H' in a 输出结果 True
not in 成员运算符 - 如果字符串中不包含给定的字符返回 True 'M' not in a 输出结果 True
==!= 两个字符串是否完全相等 a!=b 输出结果 True
><>=<= 依次比较ACSII a<b 输出结果 True

字符串常用方法/函数

注意,因为字符串是不可编辑的,所以下面的删除、替换之类的都指的是返回修改完的新串,而旧串保存不变

长度

函数 描述
len(str) 字符串长度
len(str.encode([code])) 字符串按 code 编码后的字节数,默认为 UTF-8

大小写

方法 描述
str.capitalize() 本字符串首字母大写
str.title() 所有单词首字母大写
str.upper() 所有字母大写
str.lower() 所有字母小写

查找与替换

方法 描述
str.find(sub[,start[,end]]) 返回首次找到的位置或 -1(找不到)
str.rfind(sub[,start[,end]]) 同上,但是是从右往左找
str.index(sub[,start[,end]]) find() ,但是找不到的话直接报错
str.rindex(sub[,start[,end]]) 同上,但是是从右往左找
str.count(sub[,start[,end]]) 返回找到的次数
str.replace(old,new [,max]) 返回把 old 替换为 new ,不超过 max 次的新字符串

左/右/居中对齐

方法 描述
str.ljust(width[, fillchar]) 左对齐,在右侧使用 fillchar 字符填充至 width 宽度,默认是空格
str.rjust(width[, fillchar]) 同上,但是是右对齐
str.center(width[, fillchar]) 同上,但是是居中对齐

开头/结尾

方法 描述
str.startswith(sub[,start[,end]]) 检查 str[start:end] 是否以 sub 开头
str.endswith()(sub[,start[,end]]) 同上,但是是结尾
str.strip([chars]) 删除左右两端的 chars 字符,可多个,默认空格制表符换行之类的空白字符
str.lstrip([chars]) 同上,但是仅左端
str.rstrip([chars]) 同上,但是仅右端

根据关键词分割/合并

方法 描述
str.split([sep][,maxsplit]) seq 分割字符串,默认空白字符,最多切 maxsplit 次,返回一个已经切好的列表
str.join(iterable) 上面的逆过程, iterable 可以是列表或元组等,str 是要插入的分隔符(串),返回合并好的新串
关于 str.join(iterable) 的例子

今天看见了一个用这东西的,实在是太妙了

1
print("\n".join(sys.path))

这不比直接 print(sys.path) 优雅多了?