Python字符串处理
Posted wlhk
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python字符串处理相关的知识,希望对你有一定的参考价值。
Python之正则表达式
正则表达式重在处理字符串规则
普通字符
import re
# 普通字符
result = re.findall("p", "python")
print(result, type(result))
result = re.findall("o", "I love python")
print(result, type(result))
预定义字符
模式 | 描述 |
---|---|
\\d | 匹配所有数字0-9 |
\\D | 匹配所有非数字 ^\\d |
\\w | 匹配包含下划线的字符 a-z A-Z 0-9 _ |
\\W | 匹配非正常字符(特殊字符) |
\\s | 匹配空白符、制表符、换行符 |
\\S | 匹配非空白符、制表符、换行符 ^/s |
result = re.findall(r"\\d", "I love python 123456")
print(result, type(result))
result = re.findall(r"\\D", "I love python 123456")
print(result, type(result))
result = re.findall(r"\\w", "1234567890abc_defg$%&")
print(result, type(result))
result = re.findall(r"\\W", "1234567890abc_defg$%&")
print(result, type(result))
result = re.findall(r"\\s", "123 4567 \\n890a\\tbcasd_$")
print(result, type(result))
result = re.findall(r"\\S", "123 4567 \\n890a\\tbcasd_$")
print(result, type(result))
元字符
[]是匹配一个字符,括号内是或者的关系
^结合预定义字符是代表取反
-号代表区间
result = re.findall(r"[123]", "123 4567 \\n890a\\tbcasds3_$")
print(result, type(result))
result = re.findall(r"[\\d\\s]", "123 4567 \\n890a\\tbcasds3_$")
print(result, type(result))
result = re.findall(r"[^\\d\\s]", "123 4567 \\n890a\\tbcasds3_$")
print(result, type(result))
result = re.findall(r"[1-5]", "123 4567 \\n890a\\tbcasds3_$")
print(result, type(result))
result = re.findall(r"[1-5a-d]", "123 4567 \\n890a\\tbcasds3_$")
print(result, type(result))
分组
分组是用圆括号"()"括起来的正则表达式,匹配出的内容就表示一个分组。使用分组,可以从目标字符串中提取出圆括号内正则表达式相匹配的内容
import re
string = "现在是北京时间12点10分"
pattern = re.compile(r\'\\D*(\\d1,2)\\D*(\\d1,2)\\D*\')
result = pattern.match(string)
print(result.groups())
result = re.findall(r\'\\D*(\\d1,2)\\D*(\\d1,2)\\D*\', string)
print(result)
#匹配结果是 (\'12\', \'10\')
模式 | 描述 |
---|---|
(exp) | 把括号内的正则作为一个分组,系统自动分配组号,可以通过分组号引用该分组。 |
(?P |
定义一个命名分组,分组的正则是exp,系统为该分组分配分组号,可通过分组名或分组号引用该分组。 |
(?:exp) | 定义一个不捕获分组,该分组只在当前位置匹配文本,在该分组之后,无法引用该分组,因为该分组没有分组名,没有分组号,也不会占用分组编号。 |
import re
# 命令分组
string = "现在是北京时间12点10分"
pattern = re.compile(r\'\\D*(?P<hour>\\d1,2)\\D*(?P<minute>\\d1,2)\\D*\')
result = pattern.match(string)
print(result.groupdict())
# 命名分组,用groupdict方法来获取一个字典结果
# \'hour\': \'12\', \'minute\': \'10\'
正则表达式的确在目标字符串中找到了模式,因此group()返回的是匹配到的内容,尽管两个分组也匹配到了内容,但由于是使用的是不捕获分组,因此圆括号里的内容不会被捕获,groups()返回的是空元组:
import re
# 不捕获分组
string = "现在是北京时间12点10分"
pattern = re.compile(r\'\\D*(?:\\d1,2)\\D*(?:\\d1,2)\\D*\')
result = pattern.match(string)
print(result.group())
print(result.groups())
print(result.groupdict())
# 输出结果
# 现在是北京时间12点10分
# ()
#
普通分组(exp) | 命名分组(?Pexp) | 不捕获分组 (?:exp) | |
---|---|---|---|
group | 返回匹配的内容 | 返回匹配的内容 | 返回匹配的内容 |
groups | 以元组形式返回匹配到的分组内容 | 以元组形式返回匹配到的分组内容 | 空元组 |
groupdict | 空字典 | 以字典形式返回匹配到的分组内容 | 空字典 |
对于普通分组,正则表达式引擎会默认为它们分配一个编号,从1开始,在编写整个表达式时,后面的部分可以通过编号引用前面的分组
import re
string = "现在是北京时间12点12分"
pattern = re.compile(r\'\\D*(\\d1,2)\\D*\\1\\D*\')
result = pattern.match(string)
print(result.groups()) # (\'12\',)
上面的例子中,只有一个分组(\\d1,2),它的编号是1,在表达式的后半部分,使用\\1 来复用分组1,你可能会以为,例子中的正则等价于
r\'\\D*(\\d1,2)\\D*(\\d1,2)\\D*\'
这样理解是错误的,如果你将时间改为“12点13分”, 上面的例子就无法正常运行了,原因在于引用分组是对重复出现的文本进行匹配,而不是对重复出现的模式进行匹配。虽然13可以匹配\\d1,2,但与分组1匹配到的12不相同,因此整个表达式不能匹配目标字符串。
对于命名分组,没有分组编号,而是用分组的名字,命名分组的形式是(?P
对于不捕获分组,既没有分组编号,也没有分组名称,因此无法引用不捕获分组
重复匹配
n前面的字符重复n次
m,n前面的字符最少重复m次,最多重复n次
n,前面的字符最少n次到任意次
? 代表前面的字符出现0次或者1次 0,1
+代表前面的字符至少1次,是必须有的 1,
*代表前面的字符出现0次或者任意次 0,
.代表除换行符\\n或\\r之外的任何单个字符 [ ^\\n\\r]
\\转义符
^放在最前面,$放在最后面则代表限定开头和结尾的范围
result = re.findall(r"\\d3", "123 4567 \\n890a\\tbcasds3_$")
print(result, type(result))
result = re.findall(r"\\d+?", "123 4567 \\n890a\\tbcasds3_$")
print(result, type(result))
贪婪和非贪婪
?成非贪婪模式
htmlstr = """
<td>python</td><td>$123</td><td>123123@qq.com</td>
"""
result = re.findall(r"<td>.+?</td>", htmlstr)
print(result)
result = re.findall(r"<td>(.+?)</td>", htmlstr)
print(result)
反向引用
wordstr = """
\'hello\' "python" \'love" "haha\'
"""
result = re.findall(r"[\'\\"]\\w+[\'\\"]", wordstr)
print(result)
result = re.findall(r"(\'|\\")(\\w+)(\\1)", wordstr)
print(result)
Python之字符串格式化
% 格式化字符
print("格式化的内容是 %s" % \'hello\')
s = \'hello\'
print("格式化的内容是 %s" % s)
# %[-][+][0][m][.n]格式化字符 % 参数
# m 占位宽度 -是做对齐, +是右对齐
print("格式化的内容是 |%20s|" % s)
print("格式化的内容是 |%+20s|" % s)
print("格式化的内容是 |%-20s|" % s)
# .在字符串中时截取字符串长度
print("格式化的内容是 |%20.2s|" % s)
print("格式化的内容是 |%20s|%12s|" % (\'hello\', \'2023-04-14\'))
print("格式化的内容是 |%20s|%12s|" % (\'hello world\', \'2023-04-14\'))
%d十进制 %x十六进制 %o八进制
print("格式化的内容是 |%d|" % 13)
print("格式化的内容是 |%x|" % 13)
print("格式化的内容是 |%o|" % 13)
print("格式化的内容是 |%10d|" % 13)
print("格式化的内容是 |%-10d|" % 13)
# +号右对齐时,数字会有符号
print("格式化的内容是 |%+10d|" % 13)
print("格式化的内容是 |%+10d|" % -13)
# 0在占位符之前,可生成占位0
print("格式化的内容是 |%010d|" % 13)
%f 浮点数
多个参数时要封装成元组
print("格式化的内容是 |%0.2f|" % 1234.5678)
print("格式化的内容是 |%20.2f|" % 1234.5678)
print("格式化的内容是 |%020.2f|" % 1234.5678)
print("我叫%s,今年%d岁,我是%s" %(\'张三\', 18, \'男性\'))
format格式化字符串
[index][:[[fill]align][sign][#][m][,][.n][type]]
模式 | 描述 |
---|---|
index | 参数的序号或者键 |
fill | 填充的字符 |
align | 对齐方式 <左对齐 >右对齐 ^居中对齐 =右对齐符号在最左侧 需要配合占位符宽度使用 |
sign | 符号选项 +强制对数字使用正负号 - 仅对复数使用前导负号 空格对正数使用一个’ ‘作前导,负数仍以’-\'为前导 |
# | 十六进制 八进制 二进制数前面加 0x 0o 0b |
m | 占位宽度 |
, 或 _ | 使用,作为千位分隔符 或 使用_作为千位分隔符 |
.n | 小数位数 |
type | 格式化字符类型 s d b x o f |
print("格式化的内容是 ".format(\'hello\'))
# index
print("格式化的内容是 010".format(1,2))
# s字符串
print(":s".format(\'hello\'))
print(":20s".format(\'hello\')) # 默认左对齐
print(":20.2s".format(\'hello\'))
print(":>20.2s".format(\'hello\'))
print(":^20.2s".format(\'hello\'))
print(":<20.2s".format(\'hello\'))
print(":+<20.2s".format(\'hello\')) #填充
# d x o b
print(":20d".format(13)) # 默认右对齐
print(":020d".format(13))
print(":0>20d".format(13))
print(":+^20d".format(13))
print("0:d|0:x|0:o|0:b".format(13))
print("0:d|0:#x|0:#o|0:#b".format(13))
# + - \' \'
print(":d|:d".format(13, -13))
print(":+d|:+d".format(13, -13))
print(":-d|:-d".format(13, -13))
print(": d|: d".format(13, -13))
# 浮点数 f
print(":f".format(1234.56789))
print(":.2f".format(1234.56789))
print(":20.2f".format(1234.56789))
# 参数传递
print(" ".format(1, 2, 3))
print("2 1 0".format(1, 2, 3)) # *args
print("0 0 0".format(1))
# index
print("关键字传参name-age-sex".format(name="john", age=18, sex=\'man\'))
print("关键字传参name-age:010d-sex".format(name="john", age=18, sex=\'man\'))
par = (1, 2, 3)
print("0[0]-0[1]-0[2]".format(par))
par = \'x\':1, \'y\':2, \'z\':3
print("dict: 0[x] 0[y] 0[z]".format(par))
# 千分位
print(":,.2f".format(12345678.1231412))
f-string格式化字符串
与format的用法基本一致,可以调用方法
name = \'johny\'
age = 18
salary = 1999.21
print(f"我的name,年龄是age,薪水是salary元")
print(f"我的name:.2s,年龄是age:010d,薪水是salary:,.2f元")
print(f"我的name.capitalize():.2s,年龄是age:010d,薪水是salary:,.2f元")
Python之base64
base64原理
base64模块是用来作base64编码解码,常用于小型数据的传输。编码后的数据是一个字符串,其包括a-z、A-Z、0-9、/、+共64个字符,即可用6个字节表示,写出数值就是0-63.故三个字节编码的话就变成了4个字节,如果数据字节数不是3的倍数,就不能精确地划分6位的块,此时需要在原数据后添加1个或2个零值字节,使其字节数为3的倍数,然后在编码后的字符串后添加1个或2个‘=’,表示零值字节,故事实上总共由65个字符组成。
索引 | 对应字符 | 索引 | 对应字符 | 索引 | 对应字符 | 索引 | 对应字符 |
---|---|---|---|---|---|---|---|
0 | A | 17 | R | 34 | i | 51 | z |
1 | B | 18 | S | 35 | j | 52 | 0 |
2 | C | 19 | T | 36 | k | 53 | 1 |
3 | D | 20 | U | 37 | l | 54 | 2 |
4 | E | 21 | V | 38 | m | 55 | 3 |
5 | F | 22 | W | 39 | n | 56 | 4 |
6 | G | 23 | X | 40 | o | 57 | 5 |
7 | H | 24 | Y | 41 | p | 58 | 6 |
8 | I | 25 | Z | 42 | q | 59 | 7 |
9 | J | 26 | a | 43 | r | 60 | 8 |
10 | K | 27 | b | 44 | s | 61 | 9 |
11 | L | 28 | c | 45 | t | 62 | + |
12 | M | 29 | d | 46 | u | 63 | / |
13 | N | 30 | e | 47 | v | ||
14 | O | 31 | f | 48 | w | ||
15 | P | 32 | g | 49 | x | ||
16 | Q | 33 | h | 50 | y |
base64模块
base64模块主要用于base64编码与base64解码,传入字节(或二进制),最后返回字节。
import base64
a = \'54K55Liq6LWe\'
b = base64.b64decode(a.encode(\'utf-8\'))
print(b)
print(b.decode(\'utf-8\'))
import base64
# base64编码:传入字节(或二进制),最后返回字节
b64_byt = base64.b64encode(\'hello world\'.encode(\'utf-8\'))
print(b64_byt, type(b64_byt))
# b\'aGVsbG8gd29ybGQ=\' <class \'bytes\'>
# 将字节转换成字符
b64_byt = b64_byt.decode(\'utf-8\')
print(b64_byt, type(b64_byt))
# aGVsbG8gd29ybGQ= <class \'str\'>
# base64解码:传入Base64编码后的字节或字符,最后返回字节
byt = base64.b64decode(b64_byt)
print(byt, type(byt))
# b\'hello world\' <class \'bytes\'>
# 将字节转换成字符
str = byt.decode(\'utf-8\')
print(str, type(str))
python字符串处理
字符串处理绝对是任何一门语言的重点。
str.
partition
(sep)
Split the string at the first occurrence of sep, and return a 3-tuple containing the part before the separator, the separator itself, and the part after the separator. If the separator is not found, return a 3-tuple containing the string itself, followed by two empty strings.
mystr = ‘hello,!!!world‘ print(mystr.partition(‘,‘)) # output (‘hello‘, ‘,‘, ‘!!!world‘)
str.
split
(sep=None, maxsplit=-1)
Return a list of the words in the string, using sep as the delimiter string. If maxsplit is given, at most maxsplit splits are done (thus, the list will have at most maxsplit+1
elements). If maxsplit is not specified or -1
, then there is no limit on the number of splits (all possible splits are made).
str.
join
(iterable)
Return a string which is the concatenation of the strings in iterable. A TypeError
will be raised if there are any non-string values in iterable, including bytes
objects. The separator between elements is the string providing this method.
mylist = [‘first‘, ‘second‘, ‘third‘] mystr = ‘#‘.join(mylist) print(mystr) # output: first#second#third
str.
startswith
(prefix, start, end)
Return True
if string starts with the prefix, otherwise return False
. prefix can also be a tuple of prefixes to look for. With optional start, test string beginning at that position. With optional end, stop comparing string at that position.
mystr = "this is string example....wow!!!" print(mystr.startswith(‘this‘)) print(mystr.startswith(‘is‘, 2, 4)) print(mystr.startswith(‘this‘, 2, 4))
输出如下:
True
True
False
以上是关于Python字符串处理的主要内容,如果未能解决你的问题,请参考以下文章