在 Python 中处理字符串

PythonBeginner
立即练习

介绍

在这个 Lab 中,你将获得使用 Python 中字符串(一种基本数据类型)的实践经验。你将从理解字符串基础开始,包括创建、不可变性(immutability)以及使用正向和负向索引(indexing)访问单个字符。

在此基础上,你将学习如何使用切片(slicing)提取子字符串,利用各种字符串运算符(operators)和转义字符(escape characters)进行操作和特殊格式化,并探索不同的字符串格式化方法。最后,你将深入了解常用的字符串方法,以执行搜索、替换和修改字符串内容等操作。

这是一个实验(Guided Lab),提供逐步指导来帮助你学习和实践。请仔细按照说明完成每个步骤,获得实际操作经验。根据历史数据,这是一个 初级 级别的实验,完成率为 97%。获得了学习者 100% 的好评率。

理解字符串基础和索引

在这一步,你将学习 Python 中字符串的基本概念,包括如何创建它们以及如何使用索引(indexing)访问单个字符。字符串是字符序列,也是最常见的数据类型之一。你可以使用单引号('...')或双引号("...")来创建字符串。

Python 字符串的一个关键特性是它们是不可变的(immutable),这意味着它们的内容在创建后不能被更改。任何看似修改字符串的操作,实际上都会创建一个新的字符串。

让我们来探索一下。在 WebIDE 中,从左侧文件浏览器中打开 ~/project 目录下的 string_basics.py 文件。向其中添加以下代码:

## string_basics.py

## 字符串是不可变的。将新字符串赋给变量
## 会创建一个具有新内存地址的新字符串对象。
a = "hello"
print(f"Value: {a}, ID: {id(a)}")

a = "hi"
print(f"Value: {a}, ID: {id(a)}")

要运行脚本,请在 WebIDE 中打开一个终端(Terminal -> New Terminal)并执行以下命令:

python ~/project/string_basics.py

你将看到类似以下的输出,其中 ID 值不同,证实了创建了一个新的字符串对象。

Value: hello, ID: <placeholder>
Value: hi, ID: <placeholder>

现在,让我们探索字符串索引。你可以使用字符的索引(位置)来访问单个字符。在 Python 中,第一个字符的索引从 0 开始。

修改 string_basics.py 文件以包含正向索引:

## string_basics.py
a = "Hello"

## 正向索引(从开头开始)
print("Positive Indexing:")
print(a[0])
print(a[1])
print(a[2])
print(a[3])
print(a[4])

## 访问不存在的索引将导致 IndexError。
## print(a[5])

保存文件并再次运行:

python ~/project/string_basics.py
Positive Indexing:
H
e
l
l
o

Python 也支持负向索引,它从字符串的末尾开始访问字符。最后一个字符的索引是 -1,倒数第二个是 -2,依此类推。

string_basics.py 添加负向索引的示例:

## string_basics.py
a = "Hello"

## 正向索引(从开头开始)
print("Positive Indexing:")
print(a[0])
print(a[1])
print(a[2])
print(a[3])
print(a[4])

## 负向索引(从末尾开始)
print("\nNegative Indexing:")
print(a[-5])
print(a[-4])
print(a[-3])
print(a[-2])
print(a[-1])

## 由于字符串是不可变的,你不能更改一个字符。
## 下一行将导致 TypeError: 'str' object does not support item assignment
## a[0] = "J"

保存文件并为这一步最后运行一次:

python ~/project/string_basics.py
Positive Indexing:
H
e
l
l
o

Negative Indexing:
H
e
l
l
o

字符串切片

在这一步,你将学习如何使用切片(slicing)从字符串中提取子字符串。索引(indexing)获取单个字符,而切片获取一个字符序列。

切片的基本语法是 string[start:end]。这会提取从 start 索引开始直到(但不包括)end 索引的部分。

打开 ~/project 目录下的 string_slicing.py 文件。添加以下代码来演示基本切片:

## string_slicing.py
a = "Hello World"

## 从索引 0 切片到索引 5(不包括 5)
print(a[0:5])

## 从索引 6 切片到字符串末尾
print(a[6:])

## 从开头切片到索引 5(不包括 5)
print(a[:5])

## 使用负数索引进行切片
print(a[-5:-2])

## 获取整个字符串的副本
print(a[:])

保存文件并在终端中运行:

python ~/project/string_slicing.py
Hello
World
Hello
Wor
Hello World

切片还可以接受第三个参数 step,语法为 string[start:end:step]step 值决定了切片中字符之间的间隔。

修改 string_slicing.py 以包含带步长的示例:

## string_slicing.py
a = "Hello World"

## ... (前面的代码) ...

b = "0123456789"

## 获取从头到尾每隔一个字符的字符
print(b[::2])

## 获取索引 1 到 7 之间的字符,步长为 3
print(b[1:7:3])

## 负数步长会反转方向。这会反转整个字符串。
print(b[::-1])

## 从索引 7 反向切片到索引 2(不包括 2)
print(b[7:2:-1])

保存文件并再次运行:

python ~/project/string_slicing.py
Hello
World
Hello
Wor
Hello World
02468
14
9876543210
76543

切片是宽容的(forgiving),它会自动处理超出范围的索引,从而避免错误。

string_slicing.py 添加最后几行代码以查看此行为:

## string_slicing.py
a = "Hello World"

## ... (前面的代码) ...

b = "0123456789"

## ... (前面的代码) ...

## 使用超出范围的索引进行切片
c = "Python"
## 结束索引大于字符串长度,但它工作正常。
print(c[2:100])

## 开始索引在开头之前,但它工作正常。
print(c[-100:4])

保存并运行脚本:

python ~/project/string_slicing.py
Hello
World
Hello
Wor
Hello World
02468
14
9876543210
76543
thon
Pyth

使用字符串运算符和转义字符

在这一步,你将学习用于字符串操作的常见运算符,以及如何使用转义字符(escape characters)来表示特殊字符。

Python 提供了几种用于字符串操作的运算符。innot in 运算符用于检查子字符串是否存在,+ 用于连接(concatenate)字符串,而 * 用于重复字符串。

在 WebIDE 中打开 string_operators.py 文件,并添加以下代码:

## string_operators.py

## 'in' 运算符检查子字符串是否存在于字符串中
print('e' in 'Hello')
print('x' in 'Hello')

## 'not in' 运算符是 'in' 的反向操作
print('e' not in 'Hello')
print('x' not in 'Hello')

## 连接 (+) 将两个字符串连接起来
print('Hello' + ' ' + 'World')

## 重复 (*) 将一个字符串重复给定的次数
print('=' * 20)
print('Go! ' * 3)

保存文件并运行:

python ~/project/string_operators.py
True
False
False
True
Hello World
====================
Go! Go! Go!

接下来,我们来看一下转义字符。这些是以反斜杠(\)开头的特殊序列,用于表示不可打印或特殊的字符。

打开 escape_characters.py 文件并添加以下代码:

## escape_characters.py

## 使用 \' 或 \" 在字符串中包含引号
print('It\'s a beautiful day.')
print("He said, \"Python is fun!\"")

## \n 创建一个新行
print("First line\nSecond line")

## \t 创建一个水平制表符(tab)
print("Column1\tColumn2\tColumn3")

## \\ 表示一个字面意义上的反斜杠
print("This is a backslash: \\")

## 前缀为 'r' 的原始字符串(raw string)将反斜杠视为字面字符。
## 这对于文件路径和正则表达式非常有用。
print("A normal string: C:\\Users\\new_folder")
print(r"A raw string: C:\Users\new_folder")

保存文件并运行:

python ~/project/escape_characters.py
It's a beautiful day.
He said, "Python is fun!"
First line
Second line
Column1 Column2 Column3
This is a backslash: \
A normal string: C:\Users\new_folder
A raw string: C:\Users\new_folder

格式化字符串

在这一步,你将学习 Python 中格式化字符串的现代且有效的方法。这对于通过将变量和表达式嵌入字符串中来创建动态且易读的输出来说至关重要。

虽然你可以使用 + 运算符来连接字符串,但在将字符串与非字符串类型(如数字)混合时,这种方式会变得笨拙,因为你必须使用 str() 手动进行转换。

Python 提供了更好的解决方案。最常见和推荐的方法是使用 f-strings(格式化字符串字面值)。

f-string 格式化

f-strings(格式化字符串字面值)在 Python 3.6 中引入,提供了一种简洁易读的方式,用于在字符串中嵌入表达式。你只需在字符串前加上 fF 前缀,然后在花括号 {} 中写入表达式即可。

打开 string_formatting.py 文件,并添加以下代码:

## string_formatting.py

name = "Alice"
age = 30

## 使用 f-string 嵌入变量
greeting = f"Hello, my name is {name} and I am {age} years old."
print(greeting)

## 你也可以直接嵌入表达式
print(f"In 5 years, I will be {age + 5} years old.")

保存并运行脚本:

python ~/project/string_formatting.py
Hello, my name is Alice and I am 30 years old.
In 5 years, I will be 35 years old.

格式说明符(Format Specifiers)

f-strings 还允许你使用格式说明符来控制嵌入值的格式,这些说明符跟在花括号内的冒号(:)后面。

将以下示例添加到 string_formatting.py 中:

## string_formatting.py

## ... (前面的代码) ...

pi = 3.14159265

## 将浮点数格式化为 2 位小数
print(f"The value of pi is approximately {pi:.2f}")

## 用前导零填充数字,总宽度为 8
order_id = 45
print(f"Order ID: {order_id:08}")

## 在给定空间内对齐文本(宽度为 10)
## < (左对齐), ^ (居中), > (右对齐)
text = "Python"
print(f"'{text:<10}'")
print(f"'{text:^10}'")
print(f"'{text:>10}'")

## 添加逗号作为千位分隔符
large_number = 1234567890
print(f"A large number: {large_number:,}")

保存并再次运行脚本:

python ~/project/string_formatting.py
Hello, my name is Alice and I am 30 years old.
In 5 years, I will be 35 years old.
The value of pi is approximately 3.14
Order ID: 00000045
'Python    '
'  Python  '
'    Python'
A large number: 1,234,567,890

str.format() 方法

在 f-strings 出现之前,str.format() 方法是格式化字符串的首选方式。它的工作原理是在字符串中放置占位符花括号 {},然后将值传递给 format() 方法。

将此示例添加到 string_formatting.py 的末尾:

## string_formatting.py

## ... (前面的代码) ...

## 使用 str.format() 方法
item = "moon"
cost = 99.95
statement = "The {} costs {:.2f} dollars.".format(item, cost)
print(statement)

保存并运行文件以查看输出:

python ~/project/string_formatting.py
Hello, my name is Alice and I am 30 years old.
In 5 years, I will be 35 years old.
The value of pi is approximately 3.14
Order ID: 00000045
'Python    '
'  Python  '
'    Python'
A large number: 1,234,567,890
The moon costs 99.95 dollars.

虽然 str.format() 仍然有用,但 f-strings 通常更具可读性且速度更快。

探索常用字符串方法

在这一最后一步中,你将探索一些最常见且有用的字符串对象的内置方法。这些方法执行各种操作,例如更改大小写、查找和替换文本,以及将字符串分割成列表。

请记住,字符串是不可变的(immutable),因此这些方法总是返回一个新的字符串,而不会修改原始字符串。

打开 string_methods.py 文件,并添加以下代码以查看这些方法的实际应用:

## string_methods.py

## 大小写转换方法
s1 = "Hello, World!"
print(f"Original: '{s1}'")
print(f"Upper case: '{s1.upper()}'")
print(f"Lower case: '{s1.lower()}'")
print(f"Title case: '{s1.title()}'")
print("-" * 20)

## 查找和替换
s2 = "The quick brown fox jumps over the lazy dog."
print(f"Original: '{s2}'")
## 检查字符串是否以某个子字符串开头或结尾
print(f"Starts with 'The': {s2.startswith('The')}")
print(f"Ends with 'dog.': {s2.endswith('dog.')}")
## 查找子字符串的索引(如果未找到则返回 -1)
print(f"Index of 'fox': {s2.find('fox')}")
## 将一个子字符串替换为另一个
s3 = s2.replace("brown", "red")
print(f"After replace: '{s3}'")
print("-" * 20)

## 去除空白字符
s4 = "    some whitespace    "
print(f"Original: '{s4}'")
## strip() 从两端移除,lstrip() 从左侧移除,rstrip() 从右侧移除
print(f"Stripped: '{s4.strip()}'")
print("-" * 20)

## 分割(Splitting)和连接(Joining)
s5 = "one,two,three,four"
print(f"Original: '{s5}'")
## 根据分隔符将字符串分割成子字符串列表
parts = s5.split(',')
print(f"Split list: {parts}")
## 使用分隔符将列表中的元素连接成一个单一的字符串
s6 = " ".join(parts)
print(f"Joined string: '{s6}'")

保存文件并从终端运行:

python ~/project/string_methods.py

你的输出应该如下所示:

Original: 'Hello, World!'
Upper case: 'HELLO, WORLD!'
Lower case: 'hello, world!'
Title case: 'Hello, World!'
--------------------
Original: 'The quick brown fox jumps over the lazy dog.'
Starts with 'The': True
Ends with 'dog.': True
Index of 'fox': 16
After replace: 'The quick red fox jumps over the lazy dog.'
--------------------
Original: '    some whitespace    '
Stripped: 'some whitespace'
--------------------
Original: 'one,two,three,four'
Split list: ['one', 'two', 'three', 'four']
Joined string: 'one two three four'

这只是 Python 中众多字符串方法中的一小部分。它们为处理和操作文本数据提供了强大的工具。

总结

在这个实验(Lab)中,你学习了使用 Python 字符串的基础概念。你从基础知识开始,理解了如何创建字符串以及认识到它们的不可变性(immutable)。你练习了使用正向和负向索引访问单个字符,以及使用带有起始、结束和步长参数的切片(slicing)来提取子字符串。

然后,你探索了用于字符串连接(+)和重复(*)的字符串运算符,并学习了如何使用转义字符(escape characters)在字符串中包含特殊字符。你掌握了现代字符串格式化技术,重点关注了 f-strings 及其格式说明符(format specifiers)的强大功能和可读性,同时也了解了 str.format() 方法。最后,你练习使用了常见的字符串方法,如 upper()lower()replace()strip()split()join(),以执行基本的文本处理任务。