文字处理没那么难

你有没有过这样的经历:

  • 需要从100个名字里提取出姓氏
  • 要把1000个手机号码格式化(加空格或横线)
  • 需要从文章里提取出所有邮箱地址
  • 要把文字里的敏感词替换掉

别再假装你会手动处理这些文字了,用Python吧!

字符串操作就是Python处理文字的利器,比Excel还强大!

字符串的基本操作

创建字符串

# 用单引号
s1 = 'Hello'

# 用双引号
s2 = "Hello"

# 用三引号(可以换行)
s3 = """
这是一段
很长的文字
可以换行
"""

# 如果字符串里有引号,用另一种引号包起来
s4 = "It's a dog"
s5 = '他叫我"大帅哥"'

字符串拼接

# 用+号拼接
name = "小明"
age = 25
message = name + "今年" + str(age) + "岁"
print(message)  # 输出:小明今年25岁

# 用f-string(Python 3.6+,推荐!)
message = f"{name}今年{age}岁"
print(message)  # 输出:小明今年25岁

# 用format()方法
message = "{}今年{}岁".format(name, age)
print(message)  # 输出:小明今年25岁

f-string是最推荐的方式,代码最简洁!

字符串重复

s = "哈哈"
print(s * 3)  # 输出:哈哈哈哈哈哈

字符串的索引和切片

索引(从0开始)

s = "Python"

# 正向索引(从0开始)
print(s[0])  # 输出:P
print(s[1])  # 输出:y
print(s[5])  # 输出:n

# 反向索引(从-1开始)
print(s[-1])  # 输出:n
print(s[-2])  # 输出:o
print(s[-6])  # 输出:P

切片(提取子字符串)

s = "Python"

# [起始位置:结束位置](不包括结束位置)
print(s[0:3])   # 输出:Pyt
print(s[1:4])   # 输出:yth
print(s[2:])    # 输出:thon(从第2个到结尾)
print(s[:3])    # 输出:Pyt(从开头到第3个)
print(s[:])     # 输出:Python(全部)

# 步长
print(s[::2])   # 输出:Pto(隔一个取一个)
print(s[::-1])  # 输出:nohtyP(反转字符串)

常用字符串方法

大小写转换

s = "Hello World"

# 全部大写
print(s.upper())  # 输出:HELLO WORLD

# 全部小写
print(s.lower())  # 输出:hello world

# 首字母大写
print(s.capitalize())  # 输出:Hello world

# 每个单词首字母大写
print(s.title())  # 输出:Hello World

# 大小写反转
print(s.swapcase())  # 输出:hELLO wORLD

去除空白

s = "  Hello World  "

# 去除首尾空白
print(s.strip())  # 输出:Hello World

# 去除左侧空白
print(s.lstrip())  # 输出:Hello World  

# 去除右侧空白
print(s.rstrip())  # 输出:  Hello World

# 去除指定字符
s = "xxxHello Worldxxx"
print(s.strip("x"))  # 输出:Hello World

查找和替换

s = "Hello World Hello Python"

# 查找子字符串(返回索引)
print(s.find("World"))    # 输出:6
print(s.find("xxx"))      # 输出:-1(没找到)

# 统计出现次数
print(s.count("Hello"))   # 输出:2

# 替换
print(s.replace("Hello", "Hi"))  # 输出:Hi World Hi Python
print(s.replace("Hello", "Hi", 1))  # 输出:Hi World Hello Python(只替换第一个)

判断字符串特征

s = "Python123"

# 是否以...开头
print(s.startswith("Py"))    # 输出:True
print(s.startswith("Pyt"))   # 输出:True
print(s.startswith("thon"))  # 输出:False

# 是否以...结尾
print(s.endswith("123"))     # 输出:True
print(s.endswith("23"))      # 输出:True
print(s.endswith("456"))     # 输出:False

# 是否全是数字
print("123".isdigit())       # 输出:True
print("abc".isdigit())       # 输出:False
print("123abc".isdigit())    # 输出:False

# 是否全是字母
print("abc".isalpha())       # 输出:True
print("123".isalpha())       # 输出:False
print("abc123".isalpha())    # 输出:False

# 是否全是数字或字母
print("abc123".isalnum())    # 输出:True
print("abc 123".isalnum())   # 输出:False(有空格)

分割和连接

# 分割字符串
s = "apple,banana,orange"

# 用逗号分割
fruits = s.split(",")
print(fruits)  # 输出:['apple', 'banana', 'orange']

# 用空格分割
s2 = "Hello World Python"
words = s2.split()
print(words)  # 输出:['Hello', 'World', 'Python']

# 限制分割次数
s3 = "a,b,c,d,e"
parts = s3.split(",", 2)
print(parts)  # 输出:['a', 'b', 'c,d,e']

# 连接字符串
fruits = ['apple', 'banana', 'orange']
result = ",".join(fruits)
print(result)  # 输出:apple,banana,orange

# 用空格连接
words = ['Hello', 'World', 'Python']
result = " ".join(words)
print(result)  # 输出:Hello World Python

对齐

s = "Python"

# 左对齐,宽度10,用空格填充
print(f"|{s.ljust(10)}|")  # 输出:|Python    |

# 右对齐,宽度10,用空格填充
print(f"|{s.rjust(10)}|")  # 输出:|    Python|

# 居中,宽度10,用空格填充
print(f"|{s.center(10)}|")  # 输出:|  Python  |

# 用指定字符填充
print(f"|{s.ljust(10, '*')}|")   # 输出:|Python****|
print(f"|{s.rjust(10, '*')}|")   # 输出:|****Python|
print(f"|{s.center(10, '*')}|")   # 输出:|**Python**|

实战小项目1:手机号码格式化

def format_phone_number(phone):
    """格式化手机号码:13812345678 -> 138-1234-5678"""
    phone = phone.replace("-", "").replace(" ", "")  # 先去掉横线和空格

    if len(phone) == 11 and phone.isdigit():
        return f"{phone[:3]}-{phone[3:7]}-{phone[7:]}"
    else:
        return "无效的手机号码!"

# 测试
print(format_phone_number("13812345678"))  # 输出:138-1234-5678
print(format_phone_number("138-1234-5678"))  # 输出:138-1234-5678
print(format_phone_number("138 1234 5678"))  # 输出:138-1234-5678
print(format_phone_number("123"))  # 输出:无效的手机号码!

实战小项目2:提取姓名的姓和名

def split_chinese_name(name):
    """分割中文姓名:假设前1-2个字是姓,后面是名"""
    name = name.strip()  # 去除首尾空白

    if len(name) >= 3:
        # 复姓
        surname = name[:2]
        given_name = name[2:]
    elif len(name) == 2:
        # 单姓
        surname = name[0]
        given_name = name[1]
    else:
        return "无效的姓名!"

    return f"姓:{surname},名:{given_name}"

# 测试
print(split_chinese_name("张三"))     # 输出:姓:张,名:三
print(split_chinese_name("欧阳锋"))   # 输出:姓:欧阳,名:锋
print(split_chinese_name("诸葛亮"))   # 输出:姓:诸,名:葛亮(简化处理)

实战小项目3:提取邮箱地址

import re

def extract_emails(text):
    """从文本中提取所有邮箱地址"""
    pattern = r'[\w\.-]+@[\w\.-]+\.\w+'
    emails = re.findall(pattern, text)
    return emails

text = """
请联系我:xiaoming@example.com 或 zhangsan@qq.com
如果有问题也可以联系:lisi@163.com
"""

emails = extract_emails(text)
print("找到的邮箱地址:")
for email in emails:
    print(email)

# 输出:
# 找到的邮箱地址:
# xiaoming@example.com
# zhangsan@qq.com
# lisi@163.com

实战小项目4:敏感词替换

def replace_sensitive_words(text, sensitive_words, replacement="***"):
    """替换敏感词"""
    for word in sensitive_words:
        text = text.replace(word, replacement)
    return text

sensitive_words = ["笨蛋", "傻瓜", "白痴"]
text = "你这个笨蛋!你真是个傻瓜!"

result = replace_sensitive_words(text, sensitive_words)
print(result)  # 输出:你这个***!你真是个***!

常见坑及解决方案

坑1:字符串是不可变的

s = "Hello"
s[0] = "P"  # 报错!字符串不能修改

解决: 创建新字符串

s = "Hello"
s = "P" + s[1:]  # 创建新字符串
print(s)  # 输出:Pello

坑2:忘记去除空白

name = input("请输入你的名字:")
if name == "小明":
    print("你好,小明!")  # 如果你输入了空格,条件就不成立

解决: 先去除空白

name = input("请输入你的名字:").strip()
if name == "小明":
    print("你好,小明!")

坑3:索引越界

s = "Python"
print(s[10])  # 报错!索引超出范围

解决: 先检查长度

s = "Python"
if len(s) > 10:
    print(s[10])
else:
    print("字符串长度不够")

本章小结

  • 字符串拼接+、f-string、format()
  • 索引和切片s[0]s[0:3]s[::-1]
  • 常用方法:upper()、lower()、strip()、find()、replace()、split()、join()
  • 判断方法:startswith()、endswith()、isdigit()、isalpha()
  • 实战项目:格式化手机号、分割姓名、提取邮箱、替换敏感词

字符串操作让你处理文字像Excel一样简单。下一章我们学习列表和字典,存储和管理数据!

继续学下去,马上就能做实用项目了!