首页 / 资讯中心 / 文章详情

Python3.5字符串常用操作实例详解

Python3.5字符串常用操作实例详解 ★ FEATURED ARTICLE
前言标题把版本锁在 Python 3.5这个限制很要紧所以先把结论写在最前面字符串的绝大多数常用操作从 Python 3 早期到现在几乎没有变过——切片、join、split、strip、replace、find、startswith、大小写转换、%与str.format格式化这些在 3.5 上都能正常使用。但有几个如今被大量使用的写法在 3.5 上根本不存在最常见的三个是f-string3.6 才有、str.removeprefix/str.removesuffix3.9 才有、以及 f-string 里的引号复用与多行表达式3.12 的 PEP 701 才放开。如果你手头真的是 3.5照抄现在的教程会一路报SyntaxError。另外必须提醒一个前提问题Python 3.5 已经是停止维护的版本。按 Python 官方开发者指南的版本表3.5 于 2015 年 9 月 13 日发布2020 年 9 月 30 日进入生命周期终点end-of-life此后不再有安全修复。本文按标题要求以 3.5 为基准写但会指出每段写法在后续版本里的变化建议尽快迁移到仍在安全支持期内的版本。本文所有代码都只用标准库。本机没有 Python 解释器示例未在真实解释器上执行结论按官方文档逐条核对过的 API 语义写成包括方法的返回类型与是否原地修改。一、第一条铁律字符串不可变Python 3 的str是不可变immutable的。这意味着两件事所有「看起来像修改」的方法都返回新对象原字符串不动。s.upper()、s.replace(...)、s.strip()都是如此。忘记接住返回值就会得到「我明明处理过了怎么还是老样子」的经典困惑。在循环里用拼接字符串会反复产生新对象。可读性上没问题但数据量大时应当改用列表收集、最后.join(parts)一次性拼接。这里不给出任何「快多少倍」的数字——那是需要你自己用timeit在同机上测的。# 适用于 Python 3.5s hello worldt s.upper() # 返回新字符串print(s) # hello worlds 没有被改变print(t) # HELLO WORLDparts []for word in [a, b, c]:parts.append(word)print(-.join(parts)) # a-b-cjoin 的调用者是分隔符不是列表二、按用途分类的常用操作Python 的字符串方法数量不少但按用途归类后就清晰了。下表是 3.5 上可用的主要方法及其要点。用途方法要点查找find/rfind/index/rindex/countfind找不到返回-1index找不到抛ValueError前后缀startswith/endswith可以直接传元组一次判断多种前缀判断isalpha/isdigit/isalnum/isspace/isupper/islower/istitle空字符串对它们一律返回False切分split/rsplit/splitlines/partitionsplit不传分隔符会按空白切分并合并连续空白拼接join只在字符串列表上可用元素不是str会TypeError修剪strip/lstrip/rstrip参数是字符集合不是前缀字符串填充对齐center/ljust/rjust/zfill宽度不够时才填充zfill处理正负号位置特殊大小写upper/lower/casefold/capitalize/title/swapcase做不区分大小写的比较casefold比lower更彻底替换与翻译replace/translate配str.maketransreplace可限制次数translate适合多字符批量替换关于几个细节值得单独强调strip(abc)不是去掉前缀abc而是去掉首尾属于{a,b,c}的任意字符。cbaxyzab.strip(abc)会得到xyz——这是个真会踩的坑。split(sepNone)与split( )不同前者把连续空白视作一个分隔符并丢弃首尾空白后者会切出空字符串。官方签名写作split(sepNone, maxsplit-1)。count、find、startswith这类方法支持起止下标但下标是「切片语义」超出长度不会报错只会得到空区间。3.5 上可用的两种格式化%运算符和str.format在 3.5 上都完整可用。str.format更现代支持位置参数、关键字参数、属性与索引访问。# 适用于 Python 3.5name, score 小明, 91.5# 方式一百分号格式化旧写法但在 3.5 上完全可用print(姓名%s分数%.1f % (name, score))# 方式二str.format3.5 推荐写法print(姓名{0}分数{1:.1f}.format(name, score)) # 位置print(姓名{n}分数{s:.1f}.format(nname, sscore)) # 关键字# 对齐与填充{序号:[填充字符][对齐][宽度][.精度][类型]}print({:*^20}.format(居中)) # 居中、宽度 20、用 * 填充print({:10.2f}.format(3.14159)) # 右对齐、宽度 10、保留两位小数# 也可以对字典用 ** 解包info {n: 小红, s: 88.0}print(姓名{n}分数{s:.1f}.format(**info))格式说明符的语法是[[填充]对齐][符号][宽度][,][.精度][类型]。对齐用左、右、^居中。注意 3.5 里没有 f-string所以f{name}这种写法会直接语法错误——那是 3.6 才引入的PEP 498。编码与解码3 与 2 的断崖Python 3 的str是 Unicode 字符串bytes是字节序列两者不能隐式互转。这是与 Python 2 最主要的差别之一Python 2 里文字是字节串u文字才是 Unicode 字符串Python 3 里str就是文本不需要u前缀。Python 2.7 已于 2020 年 1 月 1 日停止维护下面这些 2 的写法都不要再用print x是语句不是函数3 里必须写print(x)。unicode/basestring/long这三个类型在 3 里不存在分别统一为str/str/int。3 里str是 Unicode 语义读写文件默认编码不是字节语义需要显式声明。# 适用于 Python 3.5text 中文raw text.encode(utf-8) # str - bytesprint(raw) # b\xe4\xb8\xad\xe6\x96\x87back raw.decode(utf-8) # bytes - strprint(back text) # True# 打开文件一定要显式写 encoding否则会跟随系统区域设置with open(note.txt, w, encodingutf-8) as f:f.write(text)with open(note.txt, r, encodingutf-8) as f:print(f.read())三、3.5 用不了、但现在到处都在用的写法特性起始版本3.5 上的替代写法f-stringf{x}3.6PEP 498{0}.format(x)或%s % x等号调试写法f{x}3.8手写x repr(x)或x{0}.format(x)str.removeprefix/str.removesuffix3.9用startswith判断后切片或re.substr.isascii()3.7用all(ord(c) 128 for c in s)f-string 内复用同类引号、跨行表达式3.12PEP 701在 3.5 上根本没有 f-string用format字典合并运算符与字符串无关但常一起出现3.9PEP 584d1.update(d2)或{**d1, **d2}removeprefix/removesuffix的替代写法可以这样推演s.startswith(p)为真时取s[len(p):]否则原样返回。这正好是这两个方法在 3.9 里被加进来的原因——手写容易写错比如忘了startswith判断切片会静默截错。# 适用于 Python 3.5没有 removeprefix 时的等价写法def remove_prefix(s, prefix):if prefix and s.startswith(prefix):return s[len(prefix):]return sdef remove_suffix(s, suffix):if suffix and s.endswith(suffix):return s[:-len(suffix)]return sprint(remove_prefix(https://example, https://)) # exampleprint(remove_suffix(archive.tar.gz, .gz)) # archive.tarprint(remove_suffix(abc, )) # abc空后缀原样返回四、几个实用小例子# 适用于 Python 3.5# 1) 清理用户输入去首尾空白 合并内部连续空白raw hello world cleaned .join(raw.split())print(repr(cleaned)) # hello world# 2) 按行处理splitlines 会同时处理 \n、\r\n、\rmulti 第一行\r\n第二行\n第三行for i, line in enumerate(multi.splitlines(), 1):print(i, line)# 3) 批量字符替换用 maketrans 建表 translatetable str.maketrans({a: 1, b: 2, c: 3})print(cab.translate(table)) # 312# 4) 判断输入是否全为数字注意 isdigit 对全角数字也为 Trueprint(123.isdigit(), .isdigit(), 12.3.isdigit()) # True True False# 5) 用 partition 拆「键值」只会拆一次值里再出现分隔符也不受影响key, sep, value path/usr/local/bin.partition()print(key, sep, value) # path /usr/local/bin常见坑点❌ 以为strip(abc)是去掉前缀字符串abc。 ✅ 它的参数是字符集合会去掉首尾任意属于该集合的字符要去固定前缀请用startswith 切片。❌ 调用s.upper()、s.strip()后不接收返回值以为原变量被改了。 ✅ 字符串不可变所有方法返回新对象必须写s s.strip()或使用返回值。❌ 用index找子串找不到时抛ValueError崩掉。 ✅ 只关心存在性时用find找不到返回-1或in用index就要准备接住异常。❌ 用s.split( )处理用户输入结果切出一堆空字符串。 ✅ 不带参数调用s.split()它会按任意连续空白切分并丢弃首尾空白。❌ 用在循环里拼几百段文本。 ✅ 用列表收集后.join(parts)join的调用者是分隔符参数是可迭代对象。❌ 在 Python 3.5 上照抄 f-string 教程得到SyntaxError: invalid syntax。 ✅ 3.5 用str.format或%要用 f-string 就得升级到 3.6 及以上。❌ 用open(f.txt, r).read()而不写encoding换台机器就读出乱码。 ✅ 显式写encodingutf-8让文件读写不依赖运行环境的默认编码。❌ 用lower()做不区分大小写的比较遇到某些非英文字符仍不相等。 ✅ 涉及 Unicode 的大小写无关比较用casefold()它的折叠规则更彻底。总结分类3.5 可用3.5 不可用拼接join、——切分split、rsplit、splitlines、partition——修剪填充strip、center、ljust、zfill——格式化%、str.formatf-string3.6前后缀startswith/endswith 切片removeprefix/removesuffix3.9判断isdigit、isalpha等isascii()3.7写 3.5 的字符串代码只需要记住三点字符串不可变、strip收的是字符集合、以及 f-string 与removeprefix在这个版本上并不存在。其余操作三十年如一日地稳定把官方文档里str那一节的方法表扫一遍比记任何速查表都管用。最后再强调一次3.5 已于 2020 年 9 月结束支持新代码请用仍在安全支持期内的版本。
阅读完成 · 觉得有帮助?
咨询建站