# 第 1-7 课:字符串 ## 一、本课目标 完成本课后,你应该能够: 1. 解释字符串是什么; 2. 使用索引读取字符串中的单个字符; 3. 使用切片取得字符串的一部分; 4. 使用 `len()` 获取字符串长度; 5. 使用 `for` 遍历字符串; 6. 使用常见字符串方法清理、转换和查找文本; 7. 使用 `in` 判断字符串是否包含指定内容; 8. 使用 `split()` 分割字符串,使用 `join()` 连接文本; 9. 理解字符串不可变的含义; 10. 编写一个简单的 Agent 提示词文本分析器。 ## 二、前置知识 开始本课前,你应该已经掌握: - 创建字符串变量; - 使用 `input()` 接收字符串; - 使用 f-string 输出变量; - 使用条件判断; - 使用 `for` 循环遍历数据。 ## 三、字符串是什么 字符串(String,类型名为 `str`)是一串按照顺序排列的字符。 ```python prompt = "请帮我分析这段代码" ``` 这个字符串包含中文字符。字符串也可以包含: - 英文字母; - 数字字符; - 空格; - 标点符号; - 换行符等特殊字符。 只要内容被成对的单引号或双引号包围,Python 就会把它看作字符串: ```python name = "Bruce" age_text = "18" empty_text = "" ``` `age_text` 看起来像数字,但它的数据类型仍然是字符串。 ## 四、字符串中的字符有位置 字符串中的每个字符都有编号,这个编号称为索引(Index)。 Python 的索引从 `0` 开始: ```text 字符串: A g e n t 正索引: 0 1 2 3 4 负索引:-5 -4 -3 -2 -1 ``` 读取单个字符: ```python word = "Agent" print(word[0]) # A print(word[1]) # g print(word[-1]) # t ``` 方括号 `[]` 用于指定索引。 ### 4.1 负索引 负索引从字符串末尾开始: - `-1` 表示最后一个字符; - `-2` 表示倒数第二个字符; - 依此类推。 需要取得最后一个字符时,`word[-1]` 比先计算字符串长度更方便。 ### 4.2 索引越界 `"Agent"` 只有 5 个字符,有效正索引是 `0` 到 `4`。 ```text word[5] ``` 会产生 `IndexError`,中文可以理解为“索引超出有效范围”。 ## 五、使用 `len()` 获取长度 `len()` 返回字符串包含的字符数量: ```python prompt = "Hello" prompt_length = len(prompt) print(prompt_length) ``` 输出为 `5`。 空格和标点也会占用字符位置: ```python print(len("A B")) # 结果为 3 ``` `len()` 常用于: - 检查用户输入是否过短或过长; - 统计提示词长度; - 判断字符串是否为空; - 配合索引和循环处理文本。 ## 六、字符串切片 切片(Slicing)用于取得字符串的一部分。 基本形式: ```python 字符串[开始索引:结束索引] ``` 切片包含开始索引,不包含结束索引: ```python word = "Python" print(word[0:3]) # Pyt print(word[2:6]) # thon ``` 这种规则与 `range()` 相似:包含开始,不包含结束。 ### 6.1 省略开始或结束索引 ```python word = "Python" print(word[:3]) # 从开头到索引 3 之前:Pyt print(word[3:]) # 从索引 3 到末尾:hon print(word[:]) # 整个字符串:Python ``` ### 6.2 使用负索引切片 ```python file_name = "report.txt" print(file_name[-3:]) # txt ``` ### 6.3 指定步长 完整形式: ```python 字符串[开始索引:结束索引:步长] ``` ```python word = "Python" print(word[::2]) # Pto print(word[::-1]) # nohtyP ``` `[::-1]` 常用于反转字符串。现阶段理解其结果即可,不需要死记复杂切片组合。 ### 6.4 切片通常不会越界报错 ```python word = "Agent" print(word[0:100]) ``` 结果仍然是 `Agent`。单个索引越界通常报错,而切片结束位置超过长度时会安全地取到末尾。 ## 七、遍历字符串 字符串可以使用 `for` 逐个处理字符: ```python for character in "Agent": print(character) ``` 统计字母出现次数: ```python letter_count = 0 for character in "Agent application": if character == "a": letter_count += 1 print(letter_count) ``` 需要注意英文大小写。`"A"` 和 `"a"` 是不同字符。 ## 八、字符串方法是什么 方法(Method)是某种数据自身提供的操作。 字符串方法通常写成: ```python 字符串.方法名() ``` 例如: ```python user_input = " Python " clean_text = user_input.strip() ``` 点号 `.` 表示使用这个字符串提供的 `strip()` 方法。 方法与面向对象有关,将在后续阶段系统学习。本课先掌握常用字符串方法的用途。 ## 九、清理字符串 ### 9.1 `strip()` `strip()` 删除字符串开头和结尾的空白: ```python raw_text = " Python Agent " clean_text = raw_text.strip() print(clean_text) ``` 输出: ```text Python Agent ``` 它不会删除字符串中间的正常空格。 ### 9.2 `lstrip()` 与 `rstrip()` - `lstrip()`:只清理左侧; - `rstrip()`:只清理右侧。 处理用户输入时,`strip()` 最常用。 ## 十、转换英文字母大小写 ```python technology = "FastAPI" print(technology.lower()) # fastapi print(technology.upper()) # FASTAPI ``` 常见方法: - `lower()`:转成小写; - `upper()`:转成大写; - `title()`:让英文单词首字母大写; - `capitalize()`:让字符串首字符大写,其余英文字符转为小写。 大小写转换常用于不区分大小写的输入判断: ```python answer = input("是否继续(yes/no):").strip().lower() if answer == "yes": print("继续执行") ``` 这样输入 `YES`、`Yes` 或两侧带空格时也能正确识别。 ## 十一、替换文本 `replace()` 返回替换后的新字符串: ```python old_text = "我正在学习 Java" new_text = old_text.replace("Java", "Python") print(new_text) ``` 输出: ```text 我正在学习 Python ``` 原始变量 `old_text` 不会自动改变。 ## 十二、查找和统计 ### 12.1 使用 `in` `in` 判断某段内容是否包含在字符串中,结果是布尔值: ```python prompt = "请使用 Python 编写 Agent" contains_python = "Python" in prompt print(contains_python) ``` ### 12.2 `find()` `find()` 返回第一次出现的位置: ```python text = "Python Agent" print(text.find("Agent")) # 7 print(text.find("Java")) # -1 ``` 找不到时返回 `-1`。 ### 12.3 `count()` `count()` 统计内容出现次数: ```python text = "Agent Agent Python" print(text.count("Agent")) ``` 输出为 `2`。 ### 12.4 开头和结尾判断 ```python file_name = "agent.py" print(file_name.startswith("agent")) print(file_name.endswith(".py")) ``` `startswith()` 和 `endswith()` 都返回布尔值。 ## 十三、分割字符串 `split()` 按照指定分隔符拆分字符串: ```python technologies = "Python,FastAPI,Django" technology_list = technologies.split(",") print(technology_list) ``` 输出: ```text ['Python', 'FastAPI', 'Django'] ``` 这个结果是列表(List)。列表是可以保存多个数据的容器,将在下一课详细学习。本课只需要知道:`split()` 能把一段文本拆成多个部分。 如果不提供分隔符,`split()` 会按照连续空白进行分割: ```python words = "Python Agent 开发".split() ``` ## 十四、连接多个字符串 `join()` 使用指定字符串连接多个文本: ```python technology_list = ["Python", "FastAPI", "Django"] result = " -> ".join(technology_list) print(result) ``` 输出: ```text Python -> FastAPI -> Django ``` 可以这样理解:用 `" -> "` 把列表中的每个字符串连接起来。 被连接的数据必须是字符串。如果列表中包含整数,直接使用 `join()` 会报 `TypeError`。 ## 十五、字符串判断方法 常见判断方法: | 方法 | 作用 | | --- | --- | | `isdigit()` | 是否全部由数字字符组成 | | `isalpha()` | 是否全部由字母字符组成 | | `isalnum()` | 是否全部由字母或数字字符组成 | | `isspace()` | 是否全部由空白字符组成 | 示例: ```python age_text = "18" if age_text.isdigit(): age = int(age_text) print(f"年龄:{age}") else: print("请输入整数数字") ``` `isdigit()` 能帮助我们在调用 `int()` 前检查简单的非负整数字符串,但它不能覆盖负数、小数等所有数字形式。 ## 十六、字符串是不可变的 不可变(Immutable)表示字符串创建后,不能直接修改其中某个字符。 错误示例: ```text word = "Agent" word[0] = "a" ``` 这会产生 `TypeError`。 字符串方法通常返回一个新字符串: ```python original_text = " Python " clean_text = original_text.strip() print(original_text) print(clean_text) ``` 如果希望变量以后使用处理后的结果,需要重新赋值: ```python text = text.strip().lower() ``` ## 十七、转义字符 反斜杠 `\` 可以与其他字符组成特殊含义: | 写法 | 作用 | | --- | --- | | `\n` | 换行 | | `\t` | 制表符 | | `\"` | 在双引号字符串中表示双引号 | | `\\` | 表示一个反斜杠 | 示例: ```python print("第一行\n第二行") print("名称\t时长") ``` Windows 路径中包含反斜杠。可以使用原始字符串,在开头添加 `r`: ```python project_path = r"D:\Code\Python" ``` 原始字符串会减少反斜杠被当作转义符解释的情况。 ## 十八、多行字符串 三个双引号或三个单引号可以创建多行字符串: ```python report = """Agent 学习报告 学习方向:Python 当前状态:进行中""" print(report) ``` 多行字符串会保留代码中的换行。需要注意开头和结尾位置,避免无意中加入额外空行。 ## 十九、f-string 格式控制 f-string 除了插入变量,还能简单控制数字格式: ```python total_hours = 6.5 progress = 0.756 print(f"总时长:{total_hours:.2f} 小时") print(f"完成率:{progress:.1%}") ``` 输出: ```text 总时长:6.50 小时 完成率:75.6% ``` - `.2f`:浮点数保留两位小数; - `.1%`:转为百分比并保留一位小数。 这是常用格式,现阶段能够模仿使用即可。 ## 二十、方法链 多个字符串方法可以连续调用: ```python raw_answer = " YES " clean_answer = raw_answer.strip().lower() print(clean_answer) ``` 执行顺序从左到右: 1. `strip()` 得到 `"YES"`; 2. `lower()` 得到 `"yes"`; 3. 最终结果保存到 `clean_answer`。 方法链不宜过长。处理步骤复杂时,可以使用多个含义清晰的中间变量。 ## 二十一、运行本课示例 在 PowerShell 中执行: ```powershell cd D:\Code\Python\01_python基础\1_7_字符串 python strings.py ``` 示例无需用户输入,会依次展示索引、切片、遍历和常用字符串方法。 ## 二十二、常见错误 ### 22.1 索引从 1 开始计算 Python 字符串第一个字符的索引是 `0`,不是 `1`。 ### 22.2 切片包含结束索引 切片不包含结束索引。`text[0:3]` 取得索引 `0、1、2`。 ### 22.3 调用方法后忘记保存结果 ```python text = " Python " text.strip() print(text) ``` 原变量仍然保留空格。应写成: ```python text = text.strip() ``` ### 22.4 查找内容时忽略大小写 `"python" in "Python Agent"` 为 `False`。如果业务允许忽略大小写,可以先统一使用 `lower()`。 ### 22.5 混淆 `split()` 和 `join()` - `split()`:一个字符串拆成多个部分; - `join()`:多个字符串连接成一个字符串。 ### 22.6 直接修改字符串字符 字符串不可变,不能执行 `text[0] = "A"`。 ## 二十三、课堂练习 打开 `practice.py`,完成“Agent 提示词文本分析器”。程序需要清理用户输入,分析长度、关键词、单词数量和文件名,并生成格式化报告。 运行命令: ```powershell python practice.py ``` 建议第一次输入: ```text 请使用 Python 帮我开发一个 Agent 应用 ``` 预期能判断其中包含 `python` 和 `agent` 关键词。判断关键词时应忽略英文大小写。 ## 二十四、思考题 1. `"Agent"[0]` 和 `"Agent"[-1]` 分别是什么? 2. 为什么 `text[0:3]` 不包含索引 `3`? 3. `strip()` 会不会删除字符串中间的空格? 4. `replace()` 会直接修改原字符串吗? 5. `split()` 和 `join()` 的方向有什么不同? 6. 为什么字符串方法的返回结果经常需要重新赋值? 7. 如何忽略大小写判断文本中是否包含 `python`? ## 二十五、本课小结 - 字符串是有顺序的字符集合; - 索引从 `0` 开始,`-1` 表示最后一个字符; - 切片包含开始索引,不包含结束索引; - `len()` 返回字符数量; - 字符串可以使用 `for` 遍历; - `strip()`、`lower()`、`replace()` 等方法返回新字符串; - `in`、`find()`、`count()` 可以查找文本; - `split()` 拆分字符串,`join()` 连接多个字符串; - 字符串不可变,不能直接修改某个字符; - f-string 可以控制小数和百分比格式。 ## 二十六、验收标准 - [ ] 能使用正索引和负索引读取字符; - [ ] 能使用切片取得字符串的一部分; - [ ] 能使用 `len()` 和 `for` 分析文本; - [ ] 能清理输入并统一英文大小写; - [ ] 能查找和统计指定内容; - [ ] 能使用 `split()` 和 `join()`; - [ ] 能解释字符串不可变; - [ ] 能完成并运行 `practice.py`; - [ ] 能回答七道思考题。