master
/ 5.2.6 字符串的处理方法.ipynb

5.2.6 字符串的处理方法.ipynb @masterview markup · raw · history · blame

Notebook

常用字符串处理方法

5.11 字符串处理方法.jpg

常用字符串处理方法

方法名 描述
str.upper()/str.lower() 转换字符串str中所有字母为大写/小写
str.strip() 用于移除字符串开头、结尾指定的字符(缺省时去掉__空白字符__,包括\t、\n、\r、\x0b、\x0c等)
str.join(iterable) 以字符串str作为分隔符,将可迭代对象 iterable中字符串元素拼接为一个新的字符串。当iterable中存在非字符串元素时,返回一个TypeError 异常。
str.split(sep=None, maxsplit=-1) 根据分隔符sep将字符串str切分成__列表____默认用空白字符 (包括 \\n \\r \\t \\f 和空格)切分__对象且去掉字符串首尾的空白字符,可指定逗号或制表符等。maxsplit值存在且非 -1 时,最多切分maxsplit次。
str.count(sub[, start[, end]]) 返回 sub 在字符串str 里面出现的__次数__,如果start 或者 end 指定则返回指定范围内 sub出现的次数。
str.find(sub[, start[, end]]) 检测 sub 是否包含在字符串 str 中,如果是返回子字符串起始位置的__索引值__,否则返回-1。如果 start 和 end 指定范围,则检查是否包含在指定范围内。
str.replace(old, new[, count]) 把字符串str中的 old __替换__成 new,如果 count 指定,则替换不超过 count 次,否则有多个old子串时全部替换为new。
str.index(sub[, start[, end]]) 与find()方法一样,返回子字符串起始位置的__索引值__,如果sub不在字符串 str中会报一个异常。
for \ in \ 对字符串string进行__遍历__,依次将字符串string中的字符赋值给前面的变量var

str.upper()和str.lower()分别用于将其前面的字符串转换成大写字母和小写字母,如input().upper()可以将用户输入的字符串中的小写字母都转换成大写字母。
例如,网页上经常可以看到输入验证码时是不区分大小写的,其后台的程序一般会将用户的输入和图片中的字符都统一转成大写字母(或统一转成小写字母),再去一一比较是否一致。

In [ ]:
verification_code = 'Q3Se'.upper()  # 网页上显示的校验码中的字母转为大写
code = input().upper()              # 将输入的字符符串中的字母转为大写
if code == verification_code:       # 如果输入的字符串转大写后与验证码相同
    print('验证码正确')
else:
    print('验证码错误')

rstrip()函数用于移除字符串结尾指定的字符
strip()函数用于移除字符串开头和结尾指定的字符

In [2]:
s = '0089840'
print(s)                              # 原字符串0089840
s1 = s.rstrip('0')                    # 移除结尾的0
print(f'去掉字符串末尾的指定字符:{s1}')  # 008984
s2 = s.strip('0')                     # 去除字符串首尾0
print(f'去掉字符串首尾的指定字符:{s2}')  # 8984

当参数缺省时,默认去掉字符串首尾的空白字符(不可见字符)
__空白字符包括空格、“\t(制表符)”、“\n(换行符)”和“\r(回车符)”__等。

In [1]:
s1 = '3.1415\n'                             # 末尾有换行符
s2 = '  5678  \t'                           # 末尾有制表符,开头结尾有空格
s2 = s2.strip()                             # 去除字符串首尾空白字符
print(f'去掉字符串末尾换行符:{s1.strip()}。')  # 008984
print(f'去掉字符串首尾空格和制表符:{s2}。')     # 8984

str.join(iterable) 以字符串str作为分隔符,将可迭代对象 iterable中字符串元素拼接为一个新的字符串。
当iterable中存在非字符串元素时,返回一个TypeError 异常。

In [ ]:
ls = ['23', '59', '36']
print(':'.join(ls))  # 23:59:36
In [9]:
ls = ['23', '59', '36']
print(':'.join(ls))  # 23:59:36

str.split(sep=None, maxsplit=-1) 根据__分隔符参数sep的值__将字符串str切分成列表
缺省时根据__空白字符__切分,__连续多个分隔字符当成一个字符处理__,且忽略字符串__开头和结尾的空白字符__。 可指定逗号或制表符等符号做为分隔符号,指定用__一个空格__做分隔符时,__多个空格__将被__切分多次__
maxsplit值存在且非 -1 时,__最多切分maxsplit次__

In [1]:
s = '85 90 88 85'
ls = s.split()   # 缺省时根据空格切分
print(ls)        # ['85', '90', '88', '85']
['85', '90', '88', '85']

sep参数值缺省或为None时,忽略字符串开头和结尾的空白字符,且连续多个空白字符被视为一个分隔符。

In [3]:
s = '   workshop             n.专题讨论会    '
x = s.split()
print(x)        # ['workshop', 'n.专题讨论会']
['workshop', 'n.专题讨论会']
In [4]:
score = '85,90,88,85'
score_ls = score.split(',')  # 指定逗号为切分时的分隔符 
print(score_ls)              # ['85', '90', '88', '85']
['85', '90', '88', '85']
In [13]:
word = 'about  adv. 大约; 左右; 将近;'
word_ls = word.split(maxsplit=1)  # maxsplit值存在且非 -1 时,最多切分maxsplit次
print(word_ls)                    # ['about', 'adv. 大约; 左右; 将近;'],2个元素

指定用一个空格做分隔符时,多个空格将被切分多次

In [5]:
s = '85 90    88 85'
ls = s.split(' ')  # 根据一个空格切分,有多个空格时将切分多次
print(ls)          # ['85', '90', '', '', '', '88', '85']
['85', '90', '', '', '', '88', '85']

str.count(sub[, start[, end]])返回 子字符串sub在字符串str 里面出现的次数,如果start 或者 end 指定则返回指定范围内 sub出现的次数。

In [15]:
s = '武汉理工大学的武汉学生说武汉话很有武汉味儿'
print(s.count('武汉'))  # 3

str.replace(old, new[, count]) 把字符串str中的 old 替换成 new,如果 count 指定,则替换不超过 count 次,否则有多个old子串时全部替换为new。
替换后会产生一个新的字符串,所以要替换掉一个字符串中的多个字符,需要重复使用原字符串的名字。

In [16]:
import string


text = '''"This is great!" Hem said: "There's enough Cheese here to last us forever?" The little people felt happy and successful, and thought they were now secure.'''
symbol = string.punctuation      # '!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~'
for c in symbol:                 # 遍历标点符号
    text = text.replace(c, ' ')  # 将标点符号替换为空格,重用名字text,下次循环替换新字符串中的符号
print(text.lower())              # 字母转小写后输出
print(text.split())              # 根据空格切分为列表
print(len(text.split()))         # 切分为列表后列表的长度就是原文中单词的数量

练一练

参考上面代码,统计一个文件中的单词数量(去除文件中的标点符号,根据空格切分为列表) 提示: 下面两条语句的作用是将文件读入到一个字符串txt中 with open('/data/bigfiles/fc4fe459-801e-4c68-9caf-8edb88872024.txt', 'r', encoding='utf-8') as novel: txt = novel.read().lower() # 读文件为字符串并转小写
In [17]:
import string

with open('/data/bigfiles/fc4fe459-801e-4c68-9caf-8edb88872024.txt', 'r', encoding='utf-8') as novel:
    txt = novel.read().lower()  # 读文件为字符串并转小写
# symbols = '!"#$%&()*+,-.:;[\'][\"]<=>?@[\\]^_‘{|}~/'  # 作用同下条语句
symbols = string.punctuation    # punctuation表示所有符号
# 补充你的代码
参考答案:424124

实例 6.9 字符串加密

在一行中输入一个包括大小写字母和数字的字符串,编程将其中字母都转为大写,然后将大写字母用该字母后的第4个字母替换,其他字符原样输出,实现字符串加密。

1. 大写字母字符串 2. 大写字母前4个切下来拼接到后面 3. 输入一个字符串input() 4. 字母都转为大写upper() 5. 遍历字符串 5.1 如果当前字符包含在大写字母的字符串中(find(),得到当前字母在大写字母中的序号) a. 将大写字母用该字母后的第4个字母替换拼接(用变换了顺序的字符串中对应序号的字母替换) 5.2 否则 b. 其他字符原样拼接 6. 输出变换过的字符串
In [18]:
p = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'        # 原字符序列
s = 'EFGHIJKLMNOPQRSTUVWXYZABCD'        # 替换字符序列,s=p[4:]+p[:4]

plaincode = input().upper()             # 输入的明文字符串并将字母都转为大写
ciphertext = ''                         # 空字符串,存放加密字符串

for c in plaincode:                     # 遍历输入的明文字符串
    n = p.find(c)                       # 返回c在p中的位置序号,找不到时返回-1
    if n == -1:                         # 值为-1表示c在p中不存在,不是大写字母
        ciphertext = ciphertext + c     # 将原字符拼接到ciphertext上
    else:                               # c为大写字母,用序列s中对应位置的字母替换
        ciphertext = ciphertext + s[n]  # 替换的字符拼接到ciphertext
        
print(ciphertext)                       # 输出加密后的字符串
# 测试输入: LIFE is SHORT, you NEED PYTHON

实例 6.10 成绩查询

文件6.7 score.txt中保存一些同学各门课的成绩,编写程序,输入一个同学的名字,输出该同学python课程成绩。

姓名,C语言,Java,Python,C# 罗明,95,96,85,63 朱佳,75,93,66,85 李思,86,76,96,93 郑君,88,98,76,90 王雪,99,96,91,88 李立,82,66,100,771.输入一个同学的名字(input()) 2.打开文件,创建文件对象(open()) 3. 遍历文件对象,每次循环得到一个字符串(for ... in...) 3.1 将得到的字符串切分为列表(split()) 3.2 如果“Python”在列表中存在 a. 获取字符串“Python”的位置序号n (index()或find()) 3.3 否则如果学生名字在列表中存在 a. 输出列表序号为n的元素
In [ ]:
#打开当前路径下的文件,创建一个可遍历文件对象 f,文件的编码为 utf-8

stu_name =input()  # 输入要查询的学生姓名
with open('/data/bigfiles/3a898386-2be1-4d30-9721-624852a33686.txt', 'r', encoding='utf-8') as f:
    for line in f:                # 遍历创建的文件对象f,line为文件一行,字符串
        line_ls = line.split(',')  # 字符串切分为列表,根据逗号切分
        if 'Python' in line_ls:    # 如果“Python”在列表中存在
            n = line_ls.index('Python')  # 返回位置序号n
        elif stu_name in line_ls:    # 如果学生名在列表中存在,成员测试
            print(f'{line_ls[0]}的python成绩为{line_ls[n]}分')  # 输出序号为3的python成绩

练一练

修改以上代码,输出每位同学的总成绩. 提示: line.split(',') # 可将当前行切分为列表 line.split(',')[1:] # 可将当前行切分为列表后切取姓名以后的数据,即成绩数据,列表元素仍为字符串 map(int,ls) # 可将列表ls中的元素映射为整数类型 sum(map(int,ls)) # 可对map()对象中的元素求和
In [ ]:
#打开当前路径下的文件,创建一个可遍历文件对象 f,文件的编码为 utf-8

with open('/data/bigfiles/3a898386-2be1-4d30-9721-624852a33686.txt', 'r', encoding='utf-8') as f:
    f.readline()  # 读文件的一行,放在此处可读取标题行,略去不用,下面遍历文件对象时从第一位同学的数据开始
    # 补充你的代码
    
    
    
    
    
    
In [7]:
with open('/data/bigfiles/3a898386-2be1-4d30-9721-624852a33686.txt', 'r', encoding='utf-8') as f:
    f.readline()  # 读文件的一行,放在此处可读取标题行,略去不用,下面遍历文件对象时从第一位同学的数据开始
    # 补充你的代码
    
    
    
    
    
测试数据: 罗明的总成绩为339分 朱佳的总成绩为319分 李思的总成绩为351分 郑君的总成绩为352分 王雪的总成绩为374分 李立的总成绩为325分

字符串大小写转换

方法 描述
str.capitalize() 把字符串str的第一个字符大写
str.casefold() 返回一个字符串的大小写折叠的复制,类似于lower(),但他移除在字符串中的所有差异。例如,德语的小写字母'ß'对应于"ss",由于他已经是小写,所以lower()将不做任何处理,但casefold()会将他转换为"ss"。
str.swapcase() 翻转字符串str中的大小写字母。
str.title() 返回“标题化”的字符串str,将所有单词都是以大写开始,其余字母均为小写(见 istitle())
In [22]:
text = 'Daily briefing: AI predicts the shape of nearly all known proteins'
print(text.title())       # 每个单词首字母大写
print(text.capitalize())  # 字符串首字母大写
print(text.lower())       # 字母转小写
print(text.upper())       # 字母转大写

字符串格式输出

方法 描述
str.center(width[, fillchar]) 返回一个原字符串居中,并使用fillchar填充至长度 width 的新字符串,缺省用空格填充。
str.ljust(width) 返回一个原字符串左对齐,并使用空格填充至长度 width 的新字符串
str.zfill(width) 返回长度为 width 的字符串,原字符串str右对齐,前面填充0
str.expandtabs(tabsize=8) 把字符串str中的 tab 符号转为空格,tab 符号默认的空格数是 8。
str.format(*args, **kwargs) 格式化字符串
str.format_map(mapping) 与str.format(**mapping)类似,只是mapping是直接使用的,而不是复制到一个字典。
In [ ]:
print('欢迎光临'.center(40,'*'))
In [ ]:
print('P'+'2605'.zfill(12))  # 产生12位的字符串,不足12位时前面填充0,与字符串'P'拼接到一起

字符串搜索定位与替换

方法 描述
str.lstrip([chars]) 删除字符串 str左边的指定字符,默认去除空白字符
str.rstrip([chars]) 删除字符串 str右边的指定字符,默认去除空白字符
str.maketrans(x[, y[, z]]) maketrans()方法用于创建字符映射的转换表,对于接受两个参数的最简单的调用方式,第一个参数是字符串,表示需要转换的字符,第二个参数也是字符串,表示转换的目标。
str.translate(table[, deletechars]) 根据字符串 str给出的表转换字符串 str中的字符,要过滤掉的字符放到 deletechars参数中
str.rfind(sub[, start[, end]]) 类似于 find()函数,不过是从右边开始查找。
str.rindex(sub[, start[, end]]) 类似于 index(),不过是从右边开始。
str.rjust(width[, fillchar]) 返回一个原字符串右对齐,并使用fillchar填充至长度 width 的新字符串,fillchar缺省时用空格填充。
str.rpartition(sep) 类似于 partition()函数,不过是从右边开始查找。
str.rsplit(sep=None, maxsplit=-1) 通过sep指定分隔符对字符串进行分割并返回一个列表,默认分隔符为所有空白字符。类似于split()方法,只不过是从字符串右侧开始分割。如果指定maxsplit数量max,则最多切分为max次。

maketrans()方法和str.translate()方法结合,可以更方便的完成前面字符替换的操作:

In [3]:
import string


text = '''"This is great!" Hem said: "There's enough Cheese here to last us forever?" The little people felt happy and successful, and thought they were now secure.'''
symbol = string.punctuation      # '!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~'
for c in symbol:                 # 遍历标点符号
    text = text.replace(c, ' ')  # 将标点符号替换为空格,重用名字text,下次循环替换新字符串中的符号
print(len(text.split()))         # 切分为列表后列表的长度就是原文中单词的数量
In [2]:
import string


text = '''"This is great!" Hem said: "There's enough Cheese here to last us forever?" The little people felt happy and successful, and thought they were now secure.'''
symbol = string.punctuation      # '!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~'

text=text.translate(str.maketrans(symbol, ' '*len(symbol))) # 将标点符号替换为空格
print(len(text.split()))         # 切分为列表后列表的长度就是原文中单词的数量

实例 6.11 恺撒密码

在密码学中,恺撒密码是一种最简单且最广为人知的加密技术。他是一种替换加密的技术, 明文中的所有字母都在字母表上向后偏移3后被替换成密文。例如,所有的字母A将被替换成D,B变成E,以此类推。 输入一个字符串明文用恺撒密码对明文进行加密后输出。 可以发现,这是6.9的一个扩展,同时考虑到多种字符的变换,可用6.9的方法,下面给出一种用maketrans()和translate()方法字符映射转换方法实现的方案:

In [4]:
import string
 
plaintext = input('输入明文:')       # 输入要加密的明文字符串
lower = string.ascii_lowercase       # 小写字母,用常量可避免输入错误
upper = string.ascii_uppercase       # 大写字母
digit = string.digits                 # 数字
before = string.ascii_letters+digit        # 全部大小写字母+数字
after = lower[3:] + lower[:3] + upper[3:] + upper[:3]+digit[3:]+digit[:3]
table = ''.maketrans(before, after)  # 创建映射表
print(plaintext.translate(table))    # 输出加密后的密文字符串
print(f'加密后的文本是:{plaintext.translate(table)}')    # 格式化输出

练一练

修改上面题目,输入一个字符串明文,再输入一个正整数,代表偏移量,用恺撒密码对明文进行加密后输出。

In [34]:
# 补充你的代码
测试数据: 输入明文: The Japanese attack on Pearl Harbor 1941-The Japanese attack on Pearl Harbor officially brings the United States into World War II. 输入偏移量:4 Xli Neteriwi exxego sr Tievp Levfsv 5385-Xli Neteriwi exxego sr Tievp Levfsv sjjmgmeppc fvmrkw xli Yrmxih Wxexiw mrxs Asvph Aev MM. 加密后的文本是:Xli Neteriwi exxego sr Tievp Levfsv 5385-Xli Neteriwi exxego sr Tievp Levfsv sjjmgmeppc fvmrkw xli Yrmxih Wxexiw mrxs Asvph Aev MM.

字符串联合与分割

方法 描述
str.partition(sep) 从第一次出现sep的位置起,把字符串 str 分成一个3元素的元组(string_pre_str,str,string_post_str),如果字符串str中不包含sep则返回一个包含字符串本身的3元组,后面跟着两个空字符串。(string_pre_str , ' ', ' ')
str.splitlines([keepends]) 按照行('\r', '\r\n', '\n')分隔,返回一个包含各行作为元素的列表,如果参数 keepends 为 False,不包含换行符,如果为 True,则保留换行符。

字符串条件判断

方法 描述
str.isalnum() 如果字符串str至少有一个字符,并且所有字符都是字母或数字,则返回 True,否则返回 False。
str.isdigit() 如果字符串str只包含Unicode数字、半角数字或全角数字,则返回 True,否则返回 False。
str.isnumeric() 如果字符串str中只包含Unicode数字、半角数字、全角数字、罗马数字、汉字数字、以及①⒂⒔等类似数字,则返回True,否则返回 False。
str.isdecimal() 如果字符串str只包含十进制Unicode数字、半角数字或全角数字则返回 True,否则返回 False。
str.isalpha() 如果字符串str至少有一个字符,并且所有字符都是字母则返回 True,否则返回 False。
str.isidentifier() 检测字符串是否是字母开头。
str.islower() 如果字符串str中包含至少一个区分大小写的字符,并且所有这些字符都是小写,则返回 True,否则返回 False。
str.isprintable() 如果字符串str是空串或其中的所有字符都是可打印的,返回True,否则False。
str.isspace() 如果字符串str中只包含__空格、制表符(\\t)____回车(\\r)换行(\\n)__等空白字符,则返回 True,否则返回 False。
str.istitle() 如果字符串str是标题化的则返回 True,否则返回 False。
str.isupper() 如果字符串str中包含至少一个区分大小写的字符,并且所有这些字符都是大写,则返回 True,否则返回 False。
str.startswith(prefix[, start[, end]]) 检查字符串str是否是以 prefix 开头,是则返回 True,否则返回 False。如果start 和 end 指定值,则在指定范围内检查。
str.endswith(suffix[, start[, end]]) 检查字符串str是否以 suffix 结束,是则返回 True,否则返回 False。如果start 和 end 指定值,则在指定范围内检查。

实例 6.12 分类统计字符

用户输入一个字符串,分别统计其中小写字母、大写字母、数字、空格和其他字符的个数,并在一行内输出小写字母、大写字母、各类表示的数字、__空格__和其他字符的个数。

In [6]:
text = input()  # 输入一个字符串
upper, lower, digit, white, other = 0, 0, 0, 0, 0  # 初始化变量

for c in text:
    if c.islower():
        lower = lower + 1
    elif c.isupper():
        upper = upper + 1
    elif c.isnumeric():  # 此方法包括中文数字等多种类型的数字表示
        digit = digit + 1
    elif c == ' ':       # 此处不可用isspace(),该方法判定结果包括空格、制表符(\t)和回车(\r)换行(\n)等空白字符
        white = white + 1
    else:
        other = other + 1
        
print(f'小写字母{lower}个')
print(f'大写字母{upper}个')
print(f'各类数字{digit}个')
print(f'空白字符{white}个')
print(f'其他字符{other}个')
# The Japanese attack on Pearl Harbor 1941. 一九四一年十二月七日清晨,日本海军袭击珍珠港。

练一练

In [ ]:
修改上面的程序完成统计的同时输出每类字符
In [7]:
text = input()  # 输入一个字符串
upper, lower, digit, white, other = 0, 0, 0, 0, 0  # 初始化变量
upper_str, lower_str, digit_str, white_str, other_str = '', '', '', '', ''  # 构建每类字符串,均为空字符串
# 补充你的代码







    else:
        other = other + 1
        other_str = other_str + c
print(f'小写字母{lower}个: {lower_str}')
print(f'大写字母{upper}个: {upper_str}')
print(f'各类数字{digit}个: {digit_str}')
print(f'空白字符{white}个')
print(f'其他字符{other}个: {other_str}')
测试数据: 输入: The Japanese attack on Pearl Harbor 1941. 一九四一年十二月七日清晨,日本海军袭击珍珠港。 输出: 小写字母26个: heapaneseattackonearlarbor 大写字母4个: TJPH 各类数字11个: 1941一九四一十二七 空白字符7个 其他字符17个: .年月日清晨,日本海军袭击珍珠港。

字符串编码

方法 描述
bytes.decode(encoding="utf-8", errors="strict") 以 encoding 指定的编码格式解码为字节串对象,bytes为字符串,出错触发ValueError的异常。
str.encode(encoding="utf-8", errors="strict") 以 encoding 指定的编码格式编码字符串str为字节串对象,出错触发ValueError的异常。
In [ ]: