Langchain系列文章目录
01-玩转LangChain:从模型调用到Prompt模板与输出解析的完整指南
02-玩转 LangChain Memory 模块:四种记忆类型详解及应用场景全覆盖
03-全面掌握 LangChain:从核心链条构建到动态任务分配的实战指南
04-玩转 LangChain:从文档加载到高效问答系统构建的全程实战
05-玩转 LangChain:深度评估问答系统的三种高效方法(示例生成、手动评估与LLM辅助评估)
06-从 0 到 1 掌握 LangChain Agents:自定义工具 + LLM 打造智能工作流!
07-【深度解析】从GPT-1到GPT-4:ChatGPT背后的核心原理全揭秘
PyTorch系列文章目录
机器学习系列文章目录
Python系列文章目录
01-【Python-Day 1】告别编程恐惧:轻松掌握 Python 安装与第一个程序的 6 个步骤
02-【Python-Day 2】掌握Python基石:变量、内存、标识符及int/float/bool数据类型
03-【Python-Day 3】玩转文本:字符串(String)基础操作详解 (上)
04-【Python-Day 4】玩转文本:Python 字符串常用方法深度解析 (下篇)
文章目录
前言
大家好!在【Python-Day 3】中,我们初步探索了 Python 字符串的世界,学习了如何创建字符串、进行拼接、重复以及如何通过索引和切片访问字符串的特定部分。这些是操作字符串的基础。然而,Python 字符串的强大之处远不止于此。它内置了丰富的方法(Methods),能够帮助我们高效地处理各种文本操作任务,如查找特定内容、修改大小写、清理空白、分割文本等。
本篇作为字符串详解的下篇,我们将深入学习一系列非常实用的字符串内建方法。掌握这些方法将极大提升你处理文本数据的能力,无论是在数据清洗、日志分析还是网页信息提取等场景中都至关重要。让我们一起解锁 Python 字符串的更多技能吧!
一、测量你的字符串:获取长度 (len()
)
在处理字符串时,我们经常需要知道它包含多少个字符。Python 提供了一个非常方便的内建函数 len()
来完成这个任务。
严格来说,len()
是一个 Python 内建函数,可以用于多种序列类型(如列表、元组等),而不仅仅是字符串。但它对于获取字符串长度非常常用,因此我们在这里一并介绍。
它的工作原理很简单:你把字符串传递给 len()
函数,它就会返回该字符串中的字符总数(包括空格和特殊符号)。
my_string = "Hello, World! "
length = len(my_string)
print(f"字符串 '{my_string}' 的长度是: {length}")
# 输出: 字符串 'Hello, World! ' 的长度是: 14
# 注意:最后的空格也被计算在内
empty_string = ""
print(f"空字符串的长度是: {len(empty_string)}")
# 输出: 空字符串的长度是: 0
应用场景:
- 检查用户输入的文本长度是否符合要求。
- 在循环或处理文本前预知其大小。
- 计算文本占用的“空间”(尽管字符宽度可能不同)。
二、大海捞针:查找与替换
在文本中查找特定的子串或者替换掉某些内容是极其常见的操作。Python 提供了 find()
, index()
和 replace()
方法来高效完成这些任务。
2.1 查找子串的位置:find()
与 index()
这两个方法都用于在一个字符串中查找指定子串第一次出现的位置(索引)。它们的主要区别在于当子串不存在时的行为。
2.1.1 find()
方法:温柔的查找
find()
方法会在字符串中从左到右查找子串。
- 如果找到子串: 返回子串第一个字符的索引。
- 如果未找到子串: 返回 -1。
这种方式的好处是,即使找不到子串,程序也不会报错,而是返回一个特殊值(-1),方便我们进行后续的条件判断。
语法: string.find(substring, start=0, end=len(string))
substring
: 要查找的子串。start
(可选): 开始查找的起始索引,默认为 0。end
(可选): 结束查找的索引(不包含该索引位置),默认为字符串末尾。
text = "python is fun, python is powerful"
# 查找 'python' 第一次出现的位置
index1 = text.find('python')
print(f"'python' 第一次出现的索引: {index1}") # 输出: 0
# 查找 'is' 第一次出现的位置
index2 = text.find('is')
print(f"'is' 第一次出现的索引: {index2}") # 输出: 7
# 查找不存在的子串 'java'
index3 = text.find('java')
print(f"'java' 第一次出现的索引: {index3}") # 输出: -1
# 从索引 10 之后开始查找 'python'
index4 = text.find('python', 10)
print(f"从索引 10 后查找 'python' 的索引: {index4}") # 输出: 17
# 在索引 0 到 10 之间查找 'is'
index5 = text.find('is', 0, 10)
print(f"在 0-10 之间查找 'is' 的索引: {index5}") # 输出: 7
2.1.2 index()
方法:严格的查找
index()
方法的功能与 find()
几乎完全相同,都是查找子串第一次出现的索引。
- 如果找到子串: 返回子串第一个字符的索引。
- 如果未找到子串: 抛出
ValueError
异常。
这意味着如果使用 index()
,你需要确保子串一定存在,或者使用 try...except
结构来捕获可能发生的错误。
语法: string.index(substring, start=0, end=len(string))
(参数同 find()
)
text = "python is fun, python is powerful"
# 查找 'python' 第一次出现的位置
index1 = text.index('python')
print(f"'python' 第一次出现的索引: {index1}") # 输出: 0
# 尝试查找不存在的子串 'java'
try:
index_java = text.index('java')
print(f"'java' 第一次出现的索引: {index_java}")
except ValueError:
print("'java' 在字符串中未找到!") # 输出: 'java' 在字符串中未找到!
# # 如果不使用 try...except,下面这行会直接导致程序崩溃
# index_error = text.index('java')
# # ValueError: substring not found
2.1.3 异同点与选择
特性 | find() | index() |
---|---|---|
找到子串 | 返回索引 (>=0) | 返回索引 (>=0) |
未找到子串 | 返回 -1 | 抛出 ValueError |
用途倾向 | 查找可选子串 | 查找必需子串 |
如何选择?
- 如果你不确定子串是否存在,或者子串不存在是正常情况,并且你想基于是否找到来做不同处理,使用
find()
更方便,通过检查返回值是否为 -1 即可。 - 如果你期望子串一定存在,找不到就表示程序逻辑有问题或数据异常,应该中断或特殊处理,那么使用
index()
更合适,因为它会通过抛出异常来明确指示问题。
2.2 替换子串:replace()
方法
replace()
方法用于将字符串中的指定子串替换为另一个子串,并返回一个新的字符串(记住,字符串是不可变的!)。
语法: string.replace(old, new, count=-1)
old
: 要被替换掉的旧子串。new
: 用来替换的新子串。count
(可选): 指定最多替换几次。默认值 -1 表示替换所有出现的旧子串。
2.2.1 基本替换
替换所有出现的子串。
text = "hello world, hello python"
new_text = text.replace("hello", "hi")
print(f"原字符串: {text}") # 输出: hello world, hello python
print(f"替换后字符串: {new_text}") # 输出: hi world, hi python
# 注意:原字符串 text 本身没有改变
2.2.2 指定替换次数
只替换前 count
次出现的子串。
text = "apple pie, apple juice, apple cake"
new_text = text.replace("apple", "orange", 2) # 只替换前两次出现的 "apple"
print(f"替换前: {text}") # 输出: apple pie, apple juice, apple cake
print(f"替换后: {new_text}") # 输出: orange pie, orange juice, apple cake
重要提示: replace()
返回的是一个新的字符串。如果你想保留替换后的结果,需要将其赋值给一个变量(可以是原变量名,也可以是新变量名)。
三、字母变形记:大小写转换
Python 字符串提供了多种方法来方便地转换字母的大小写。
3.1 全部大写:upper()
将字符串中所有的字母转换为大写形式。
message = "Hello Python!"
upper_message = message.upper()
print(f"原字符串: {message}") # 输出: Hello Python!
print(f"转换后: {upper_message}") # 输出: HELLO PYTHON!
3.2 全部小写:lower()
将字符串中所有的字母转换为小写形式。这在进行不区分大小写的比较或查找时非常有用。
title = "Data Analysis with Python"
lower_title = title.lower()
print(f"原字符串: {title}") # 输出: Data Analysis with Python
print(f"转换后: {lower_title}") # 输出: data analysis with python
3.3 首字母大写:capitalize()
将字符串的第一个字符转换为大写,其余所有字符转换为小写。
sentence = "pYtHoN Is FuN."
capitalized_sentence = sentence.capitalize()
print(f"原字符串: {sentence}") # 输出: pYtHoN Is FuN.
print(f"转换后: {capitalized_sentence}") # 输出: Python is fun.
3.4 每个单词首字母大写:title()
将字符串中每个单词的第一个字母转换为大写,其余字母转换为小写。单词通常以空格或标点符号分隔。
book_title = "the lord of the rings"
titled_book_title = book_title.title()
print(f"原字符串: {book_title}") # 输出: the lord of the rings
print(f"转换后: {titled_book_title}") # 输出: The Lord Of The Rings
# 注意对带撇号等情况的处理
name = "o'reilly"
print(name.title()) # 输出: O'Reilly
3.5 应用场景对比
upper()
,lower()
: 常用于标准化输入(如用户名、邮箱),或进行不区分大小写的文本比较。capitalize()
: 适用于句子或标题的规范化,确保句首大写。title()
: 适用于格式化人名、书名、地名等。
四、清理空白符:strip()
, lstrip()
, rstrip()
用户输入或从文件中读取的数据常常在开头或结尾包含多余的空白字符(空格、制表符 \t
、换行符 \n
等)。这些空白符可能会干扰后续的处理和比较。Python 提供了 strip()
系列方法来清除它们。
4.1 去除两端空白:strip()
strip()
方法默认去除字符串开头和结尾的所有空白字符。
raw_input = " some important data \n\t "
cleaned_input = raw_input.strip()
print(f"原始输入: '{raw_input}'")
print(f"清理后: '{cleaned_input}'")
# 输出:
# 原始输入: ' some important data
# '
# 清理后: 'some important data'
4.2 去除左侧空白:lstrip()
lstrip()
(left strip) 只去除字符串开头的空白字符。
left_padded = " leading spaces"
stripped_left = left_padded.lstrip()
print(f"原始: '{left_padded}'")
print(f"lstrip后: '{stripped_left}'") # 输出: 'leading spaces'
4.3 去除右侧空白:rstrip()
rstrip()
(right strip) 只去除字符串结尾的空白字符。
right_padded = "trailing spaces \n"
stripped_right = right_padded.rstrip()
print(f"原始: '{right_padded}'")
print(f"rstrip后: '{stripped_right}'") # 输出: 'trailing spaces'
4.4 指定去除字符
strip()
, lstrip()
, rstrip()
都可以接受一个可选参数,该参数是一个字符串,指定要去除的字符集合。
url = "www.example.com//"
cleaned_url = url.rstrip('/') # 去除末尾的 '/'
print(f"原始URL: {url}") # 输出: www.example.com//
print(f"清理后URL: {cleaned_url}") # 输出: www.example.com
csv_data = ",,,1,2,3,,,"
cleaned_data = csv_data.strip(',') # 去除两端的 ','
print(f"原始CSV: {csv_data}") # 输出: ,,,1,2,3,,,
print(f"清理后CSV: {cleaned_data}") # 输出: 1,2,3
注意: 当提供参数时,这些方法会移除两端(或指定一端)所有在参数字符串中出现的字符,直到遇到不在参数字符串中的字符为止。例如 "..ab..c..".strip('.c')
会得到 "ab.."
。
五、分分合合:分割与连接
在处理文本时,经常需要将一个长字符串按某种规则拆分成多个部分(列表),或者将一个列表中的多个字符串组合成一个单一的字符串。split()
和 join()
就是为此而生。
5.1 字符串分割:split()
split()
方法根据指定的分隔符将字符串分割成一个子字符串列表。
语法: string.split(separator=None, maxsplit=-1)
separator
(可选): 指定用于分割的分隔符。如果省略或为None
,则默认使用连续的空白字符(空格、\t
、\n
等)作为分隔符,并且结果中不包含空字符串。如果指定了分隔符,即使连续出现分隔符,也会产生空字符串。maxsplit
(可选): 指定最大分割次数。分割maxsplit
次后,剩余的部分将作为列表的最后一个元素。默认 -1 表示不限制次数。
5.1.1 默认按空白分割
sentence = "This is a sample sentence."
words = sentence.split() # 默认按空白分割
print(words)
# 输出: ['This', 'is', 'a', 'sample', 'sentence.']
multi_space = "Split by \t multiple \n spaces"
parts = multi_space.split()
print(parts)
# 输出: ['Split', 'by', 'multiple', 'spaces']
5.1.2 指定分隔符
csv_line = "Alice,25,New York"
fields = csv_line.split(',') # 按逗号分割
print(fields)
# 输出: ['Alice', '25', 'New York']
path = "/usr/local/bin/python"
components = path.split('/')
print(components)
# 输出: ['', 'usr', 'local', 'bin', 'python'] (注意开头的 '/' 导致第一个元素为空)
5.1.3 指定分割次数
data = "user:john:doe:/home/john:/bin/bash"
# 只分割前两次出现的 ':'
parts = data.split(':', 2)
print(parts)
# 输出: ['user', 'john', 'doe:/home/john:/bin/bash']
5.2 列表连接成字符串:join()
join()
方法的作用与 split()
相反。它使用调用该方法的字符串作为分隔符,将一个包含字符串的可迭代对象(通常是列表)中的所有元素连接成一个单一的字符串。
语法: separator_string.join(iterable)
separator_string
: 你希望用作元素之间连接符的字符串。iterable
: 包含要连接的字符串元素的列表、元组等。注意: 可迭代对象中的所有元素都必须是字符串类型,否则会抛出TypeError
。
5.2.1 使用指定分隔符连接
word_list = ['Python', 'is', 'awesome']
# 使用空格连接
sentence = " ".join(word_list)
print(sentence) # 输出: Python is awesome
# 使用 '-' 连接
hyphenated = "-".join(word_list)
print(hyphenated) # 输出: Python-is-awesome
# 使用空字符串连接(无分隔符)
combined = "".join(word_list)
print(combined) # 输出: Pythonisawesome
5.2.2 对 join()
的常见误解
初学者可能会错误地尝试 list.join(separator)
,这是不对的。记住: 是分隔符字符串调用 join()
方法,并将列表作为参数传入。
# 错误的方式:
# my_list = ['a', 'b', 'c']
# result = my_list.join('-') # 这会报错 AttributeError
# 正确的方式:
my_list = ['a', 'b', 'c']
separator = '-'
result = separator.join(my_list) # 使用分隔符字符串调用 join
print(result) # 输出: a-b-c
split()
与 join()
的关系图示 (Mermaid):
graph LR
A[字符串: "Python is fun"] -- split(' ') --> B(列表: ['Python', 'is', 'fun']);
B -- ' '.join() --> A;
六、真假判断:字符串验证方法
Python 字符串还提供了一系列以 is
开头的方法,用于判断字符串的内容是否符合某种特征,它们都返回布尔值 (True
或 False
)。这对于数据验证非常有用。
6.1 开头与结尾判断:startswith()
和 endswith()
startswith(prefix, start=0, end=len(string))
: 判断字符串是否以指定的prefix
开头。endswith(suffix, start=0, end=len(string))
: 判断字符串是否以指定的suffix
结尾。
它们也可以接受可选的 start
和 end
参数来指定检查的范围。prefix
和 suffix
还可以是一个包含多个可能选项的元组。
filename = "document.pdf"
url = "https://www.google.com"
print(f"'{filename}' 是否以 'doc' 开头? {filename.startswith('doc')}") # True
print(f"'{filename}' 是否以 '.pdf' 结尾? {filename.endswith('.pdf')}") # True
print(f"'{filename}' 是否以 '.txt' 结尾? {filename.endswith('.txt')}") # False
print(f"'{url}' 是否以 'http' 或 'https' 开头? {url.startswith(('http', 'https'))}") # True
# 检查子串
text = "abcdefg"
print(f"'{text}' 的索引 2 到 5 ('cde') 是否以 'cd' 开头? {text.startswith('cd', 2, 5)}") # True
6.2 内容类型判断:isdigit()
, isalpha()
, isspace()
6.2.1 是否只包含数字:isdigit()
如果字符串中所有字符都是数字(0-9),并且至少有一个字符,则返回 True
,否则返回 False
。注意:它不能识别小数点、负号。
num_str1 = "12345"
num_str2 = "123.45" # 包含小数点,不是 True
num_str3 = "-100" # 包含负号,不是 True
empty_str = "" # 空字符串,不是 True
print(f"'{num_str1}'.isdigit()? {num_str1.isdigit()}") # True
print(f"'{num_str2}'.isdigit()? {num_str2.isdigit()}") # False
print(f"'{num_str3}'.isdigit()? {num_str3.isdigit()}") # False
print(f"'{empty_str}'.isdigit()? {empty_str.isdigit()}") # False
6.2.2 是否只包含字母:isalpha()
如果字符串中所有字符都是字母(a-z, A-Z),并且至少有一个字符,则返回 True
,否则返回 False
。空格、数字、标点符号都不算字母。
alpha_str1 = "HelloWorld"
alpha_str2 = "Hello World" # 包含空格
alpha_str3 = "Python3" # 包含数字
empty_str = ""
print(f"'{alpha_str1}'.isalpha()? {alpha_str1.isalpha()}") # True
print(f"'{alpha_str2}'.isalpha()? {alpha_str2.isalpha()}") # False
print(f"'{alpha_str3}'.isalpha()? {alpha_str3.isalpha()}") # False
print(f"'{empty_str}'.isalpha()? {empty_str.isalpha()}") # False
6.2.3 是否只包含空白:isspace()
如果字符串中所有字符都是空白字符(空格
、制表符 \t
、换行符 \n
、回车符 \r
等),并且至少有一个字符,则返回 True
,否则返回 False
。
space_str1 = " \t\n "
space_str2 = " not only spaces "
empty_str = ""
print(f"'{space_str1}'.isspace()? {space_str1.isspace()}") # True
print(f"'{space_str2}'.isspace()? {space_str2.isspace()}") # False
print(f"'{empty_str}'.isspace()? {empty_str.isspace()}") # False
6.3 其他常用判断方法
还有一些其他的 is...()
方法也很有用:
isalnum()
: 如果所有字符都是字母或数字,且至少有一个字符,返回True
。islower()
: 如果所有字母字符都是小写,且至少有一个字母字符,返回True
。isupper()
: 如果所有字母字符都是大写,且至少有一个字母字符,返回True
。istitle()
: 如果字符串是标题化的(每个单词首字母大写,其余小写),且至少有一个字符,返回True
。
print("'Python3'.isalnum()? ", 'Python3'.isalnum()) # True
print("'python'.islower()? ", 'python'.islower()) # True
print("'PYTHON'.isupper()? ", 'PYTHON'.isupper()) # True
print("'Hello World'.istitle()? ", 'Hello World'.istitle()) # True
print("'HelloWorld'.istitle()? ", 'HelloWorld'.istitle()) # False (第二个 W 不是单词首字母)
这些判断方法在需要验证用户输入格式、解析特定格式的文本文件时非常有用。
七、总结
恭喜你!完成了 Python 字符串常用方法的学习。在本篇中,我们深入探讨了如何利用 Python 强大的内建方法来高效地处理和操作文本信息。回顾一下我们掌握的核心技能:
- 获取长度: 使用
len()
函数可以轻松得知字符串包含的字符数量。 - 查找与替换:
find()
: 查找子串位置,找不到返回 -1(安全查找)。index()
: 查找子串位置,找不到抛出ValueError
(严格查找)。replace()
: 替换字符串中的子串,返回新字符串(支持指定次数)。
- 大小写转换:
upper()
: 全部转大写。lower()
: 全部转小写。capitalize()
: 句首字母大写,其余小写。title()
: 每个单词首字母大写。
- 清理空白:
strip()
: 去除字符串两端的空白(或指定字符)。lstrip()
: 去除左侧空白(或指定字符)。rstrip()
: 去除右侧空白(或指定字符)。
- 分割与连接:
split()
: 将字符串按分隔符分割成列表(默认按空白)。join()
: 使用指定字符串连接列表中的元素成新字符串。
- 内容判断:
startswith()
/endswith()
: 检查字符串的开头或结尾。isdigit()
,isalpha()
,isspace()
,isalnum()
,islower()
,isupper()
,istitle()
: 判断字符串内容是否符合特定类型或格式。
掌握这些字符串方法是 Python 编程中处理文本的基础,也是进行更复杂任务(如数据清洗、文件解析、网络爬虫等)的必备技能。请务必多加练习,尝试将它们应用到实际的小项目中。
在下一篇【Python-Day 5】中,我们将学习如何更优雅、更灵活地格式化字符串输出,让你的程序打印信息更加美观和专业。敬请期待!