字符串
ASCII码采用1个字节来对字符进行编码,最多只能表示256个符号。
UTF-8以3个字节表示中文
GB2312是我国制定的中文编码,使用1个字节表示英语,2个字节表示中文;GBK是GB2312的扩充,而CP936是微软在GBK基础上开发的编码方式。GB2312、GBK和CP936都是使用2个字节表示中文。
Python 3.x完全支持中文字符,默认使用UTF8编码格式,无论是一个数字、英文字母,还是一个汉字,都按一个字符对待和处理。(字符并非字节)
在Python中,字符串属于不可变序列类型,除了支持序列通用方法(包括分片操作)以外,还支持特有的字符串操作方法。
常用格式字符
格式字符 |
说明 |
%s |
字符串 (采用str()的显示) |
%r |
字符串 (采用repr()的显示) |
%c |
单个字符 |
%b |
二进制整数 |
%d |
十进制整数 |
%i |
十进制整数 |
%o |
八进制整数 |
%x |
十六进制整数 |
%e |
指数 (基底写为e) |
%E |
指数 (基底写为E) |
%f、%F、%F |
浮点数 |
%g |
指数(e)或浮点数 (根据显示长度) |
%G |
指数(E)或浮点数 (根据显示长度) |
%% |
字符"%""%" |
字符串常用方法
find()和rfind方法分别用来查找一个字符串在另一个字符串指定范围(默认是整个字符串)中首次和最后一次出现的位置,如果不存在则返回-1;
index()和rindex()方法用来返回一个字符串在另一个字符串指定范围中首次和最后一次出现的位置,如果不存在则抛出异常;
count()方法用来返回一个字符串在另一个字符串中出现的次数。
split()和rsplit()方法分别用来以指定字符为分隔符,将字符串左端和右端开始将其分割成多个字符串,并返回包含分割结果的列表;如果不指定分隔符,则字符串中的任何空白符号(包括空格、换行符、制表符等等)都将被认为是分隔符,返回包含最终分割结果的列表。split()和rsplit()方法还允许指定最大分割次数
partition()和rpartition()用来以指定字符串为分隔符将原字符串分割为3部分,即分隔符前的字符串、分隔符字符串、分隔符后的字符串,如果指定的分隔符不在原字符串中,则返回原字符串和两个空字符串。
join()方法用于字符串连接,不推荐使用+运算符连接字符串,优先使用join()方法,因为join()方法效率更高。
lower()返回小写字符串
upper()返回大写字符串
capitalize()字符串首字符大写
title()每个单词的首字母大写
swapcase()大小写互换
replace()查找替换,类似于“查找与替换”功能
maketrans()方法用来生成字符映射表,而translate()方法用来根据映射表中定义的对应关系转换字符串并替换其中的字符,使用这两个方法的组合可以同时处理多个不同的字符,replace()方法则无法满足这一要求。
#创建映射表,将字符"abcdef123"一一对应地转换为"uvwxyz@#$"
>>> table = ''.maketrans('abcdef123', 'uvwxyz@#$')
>>> s = "Python is a greate programming language. I like it!"
#按映射表进行替换
>>> s.translate(table)
'Python is u gryuty progrumming lunguugy. I liky it!'
strip()删除指定字符,默认是删除空白字符
rstrip()删除字符串右端指定字符
lstrip()删除字符串左端指定字符
这三个函数的参数指定的字符串并不作为一个整体对待,而是在原字符串的两侧、右侧、左侧删除参数字符串中包含的所有字符,一层一层地从外往里扒。
eval() 函数用来执行一个字符串表达式,并返回表达式的值。小心使用!
startswith()、endswith(),判断字符串是否以指定字符串开始或结束
center()、ljust()、rjust(),返回指定宽度的新字符串,原字符串居中、左对齐或右对齐出现在新字符串中,如果指定宽度大于字符串长度,则使用指定的字符(默认为空格)进行填充。
zfill()返回指定宽度的字符串,在左侧以字符0进行填充。指定宽度小于字符串长度时,返回字符串本身。
isalnum()检测字符串是否由字母和数字组成。
isalpha()检测字符串是否只由字母组成。
isdigit()检测字符串是否只由数字组成。
isdecimal()检查字符串是否只包含十进制字符。这种方法只存在于unicode对象。
isnumeric()检测字符串是否只由数字组成。这种方法是只针对unicode对象。支持汉子数字、罗马数字
isspace()检测字符串是否只由空格组成。
isupper()检测字符串中所有的字母是否都为大写。
islower()检测字符串是否由小写字母组成。
istitle()检测字符串中所有的单词拼写首字母是否为大写,且其他字母为小写。
Pytho标准库zlib中提供的compress()和decompress()函数可以用于数据的压缩和解压缩,在压缩字符串之前需要先编码为字节串。信息重复度越高,压缩比越大。
正则表达式
元字符 |
功能说明 |
. |
匹配除换行符以外的任意单个字符 |
* |
匹配位于*之前的字符或子模式的0次或多次出现 |
+ |
匹配位于+之前的字符或子模式的1次或多次出现 |
- |
在[]之内用来表示范围 |
| |
匹配位于|之前或之后的字符 |
^ |
匹配行首,匹配以^后面的字符开头的字符串 |
$ |
匹配行尾,匹配以$之前的字符结束的字符串 |
? |
匹配位于?之前的0个或1个字符。当此字符紧随任何其他限定符(*、+、?、{n}、{n,}、{n,m})之后时,匹配模式是“非贪心的”。“非贪心的”模式匹配搜索到的、尽可能短的字符串,而默认的“贪心的”模式匹配搜索到的、尽可能长的字符串。例如,在字符串“oooo”中,“o+?”只匹配单个“o”,而“o+”匹配所有“o” |
\ |
表示位于\之后的为转义字符 |
\num |
此处的num是一个正整数。例如,“(.)\1”匹配两个连续的相同字符 |
\f |
换页符匹配 |
\n |
换行符匹配 |
\r |
匹配一个回车符 |
\b |
匹配单词头或单词尾 |
\B |
与\b含义相反\b含义相反 |
\d |
匹配任何数字,相当于[0-9] |
\D |
与\d含义相反,等效于[^0-9] |
\s |
匹配任何空白字符,包括空格、制表符、换页符,与 [ \f\n\r\t\v] 等效 |
\S |
与\s含义相反 |
\w |
匹配任何字母、数字以及下划线,相当于[a-zA-Z0-9_] |
\W |
与\w含义相反\w含义相反,与“[^A-Za-z0-9_]”等效 |
() |
将位于()内的内容作为一个整体来对待 |
{} |
按{}中的次数进行匹配 |
[] |
匹配位于[]中的任意一个字符 |
[^xyz] |
反向字符集,匹配除x、y、z之外的任何字符 |
[a-z] |
字符范围,匹配指定范围内的任何字符 |
[^a-z] |
反向范围字符,匹配除小写英文字母之外的任何字符 |
最简单的正则表达式是普通字符串,可以匹配自身
'[pjc]ython'可以匹配'python'、'jython'、'cython'
'[a-zA-Z0-9]'可以匹配一个任意大小写字母或数字
'[^abc]'可以一个匹配任意除'a'、'b'、'c'之外的字符
'python|perl'或'p(ython|erl)'都可以匹配'python'或'perl'
子模式后面加上问号表示可选。r'(http://)?(www\.)?python\.org'只能匹配'http://www.python.org'、'http://python.org'、'www.python.org'和'python.org'
'^http'只能匹配所有以'http'开头的字符串
(pattern)*:允许模式重复0次或多次
(pattern)+:允许模式重复1次或多次
(pattern){m,n}:允许模式重复m~n次
'(a|b)*c':匹配多个(包含0个)a或b,后面紧跟一个字母c。
'ab{1,}':等价于'ab+',匹配以字母a开头后面带1个至多个字母b的字符串。
'^[a-zA-Z]{1}([a-zA-Z0-9._]){4,19}$':匹配长度为5-20的字符串,必须以字母开头、可带数字、“_”、“.”的字串。
'^(\w){6,20}$':匹配长度为6-20的字符串,可以包含字母、数字、下划线。
'^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$':检查给定字符串是否为合法IP地址。
'^(13[4-9]\d{8})|(15[01289]\d{8})$':检查给定字符串是否为移动手机号码。
'^[a-zA-Z]+$':检查给定字符串是否只包含英文字母大小写。
'^\w+@(\w+\.)+\w+$':检查给定字符串是否为合法电子邮件地址。
'^(\-)?\d+(\.\d{1,2})?$':检查给定字符串是否为最多带有2位小数的正数或负数。
'[\u4e00-\u9fa5]':匹配给定字符串中所有汉字。
'^\d{18}|\d{15}$':检查给定字符串是否为合法身份证格式。
'\d{4}-\d{1,2}-\d{1,2}':匹配指定格式的日期,例如2016-1-31。
'^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[,._]).{8,}$':检查给定字符串是否为强密码,必须同时包含英语字母大写字母、英文小写字母、数字或特殊符号(如英文逗号、英文句号、下划线),并且长度必须至少8位。
"(?!.*[\'\"\/;=%?]).+":如果给定字符串中包含’、”、/、;、=、%、?则匹配失败。
'(.)\\1+':匹配任意字符的一次或多次重复出现。
'((?P<f>\b\w+\b)\s+(?P=f))':匹配连续出现两次的单词。
'((?P<f>.)(?P=f)(?P<g>.)(?P=g))':匹配AABB形式的成语或字母组合。
re模块主要方法
方法 |
功能说明 |
compile(pattern[, flags]) |
创建模式对象 |
escape(string) |
将字符串中所有特殊正则表达式字符转义 |
findall(pattern, string[, flags]) |
列出字符串中模式的所有匹配项 |
finditer(pattern, string, flags=0) |
返回包含所有匹配项的迭代对象,其中每个匹配项都是match对象 |
fullmatch(pattern, string, flags=0) |
尝试把模式作用于整个字符串,返回match对象或None |
match(pattern, string[, flags]) |
从字符串的开始处匹配模式,返回match对象或None |
purge() |
清空正则表达式缓存 |
search(pattern, string[, flags]) |
在整个字符串中寻找模式,返回match对象或None |
split(pattern, string[, maxsplit=0]) |
根据模式匹配项分隔字符串 |
sub(pat, repl, string[, count=0]) |
将字符串中所有pat的匹配项用repl替换,返回新字符串,repl可以是字符串或返回字符串的可调用对象,该可调用对象作用于每个匹配的match对象 |
subn(pat, repl, string[, count=0]) |
将字符串中所有pat的匹配项用repl替换,返回包含新字符串和替换次数的二元元组,repl可以是字符串或返回字符串的可调用对象,该可调用对象作用于每个匹配的match对象 |
直接使用re模块方法:
import re text = 'alpha. brta....gamma delta'
print(re.split(r'[. ]+', text)) # 以.和空格为分隔符进行分隔,r表示原生字符
# ['alpha', 'brta', 'gamma', 'delta'] text = 'alpha. brta....gamma delta'
print(re.split(r'[. ]+', text, maxsplit=2)) # 以.和空格为分隔符进行分隔,r表示原生字符,最大分隔次数为2
# ['alpha', 'brta', 'gamma delta'] text = 'alpha. brta....gamma delta'
pat = '[a-zA-Z]+'
print(re.findall(pat, text)) # 查找所有单词
# ['alpha', 'brta', 'gamma', 'delta'] s = "It's a very good good idea"
print(re.sub(r'(\b\w+) \1', r'\1', s)) # 去除重复的单词,\1对应的是前面的第一个括号所匹配到的字符串
# It's a very good idea print(re.sub('a', lambda x: x.group(0).upper(), 'aaa abc abde'))
# AAA ABc ABde
print(re.sub('[a-z]', lambda x: x.group(0).upper(), 'aaa abc abde'))
# AAA ABC ABDE
print(re.sub('[a-zA-z]', lambda x: chr(ord(x.group(0)) ^ 32), 'aaa aBc abDe')) # ord()返回字符的ASCII码,与32异或之后,用chr()返回对应的字符
# AAA AbC ABdE print(re.escape('http://www.baidu.com'))
# http\:\/\/www\.baidu\.com example = 'Beautiful is better b than ugly.'
print(re.findall(r'\bb.+?\b', example))
# ?表示非贪心模式,结果为 ['better', 'b ']
# 去掉问号后,为贪心模式,结果为 ['better b than ugly'] example = 'Beautiful is better b than ugly.'
print(re.findall(r'\Bh.+?\b', example))
# 表示不以h开头且内部函数h的单词的一部分,结果为 ['han'] example = 'Beautiful is better b than ugly.'
print(re.findall(r'\b\w.+?\b', example))
# 匹配所有的单词,结果为 ['Beautiful', 'is', 'better', 'b ', 'than', 'ugly'] s = '<html><head>This is head.</head><body>This is body.</body></html>'
pattern = r'<html><head>(.+)</head><body>(.+)</body></html>'
result = re.search(pattern, s)
print(result.group(1))
# 第一个子模式,结果为 This is head.
print(result.group(2))
# 第二个子模式,结果为 This is body. m = re.match(r"(?P<first_name>\w+) (?P<last_name>\w+)", "Malcolm Reynolds")
print(m.group('first_name')) # 使用命名的子模式
# Malcolm
print(m.group('last_name')) # 使用命名的子模式
# Reynolds
print(m.groups()) # 以元组的形式返回
# ('Malcolm', 'Reynolds')
print(m.groupdict()) # 以字典的形式返回
# {'first_name': 'Malcolm', 'last_name': 'Reynolds'}
使用正则表达式对象:
match(string[, pos[, endpos]])方法在字符串开头或指定位置进行搜索,模式必须出现在字符串开头或指定位置;
search(string[, pos[, endpos]])方法在整个字符串或指定范围中进行搜索;
正则表达式对象的match方法和search方法匹配成功后返回match对象。match对象的主要方法有:
group():返回匹配的一个或多个子模式内容
groups():返回一个包含匹配的所有子模式内容的元组
groupdict():返回包含匹配的所有命名子模式内容的字典
start():返回指定子模式内容的起始位置
end():返回指定子模式内容的结束位置的前一个位置
span():返回一个包含指定子模式内容起始位置和结束位置前一个位置的元组。
findall(string[, pos[, endpos]])方法字符串中查找所有符合正则表达式的字符串并以列表形式返回。
正则表达式对象的sub(repl, string[, count = 0])和subn(repl, string[, count = 0])方法用来实现字符串替换功能,其中参数repl可以为字符串或返回字符串的可调用对象。
正则表达式对象的split(string[, maxsplit = 0])方法用来实现字符串分隔。
使用正则表达式提取字符串中的电话号码:
import re telNumber = '''Suppose my Phone No. is 0535-1234567, yours is 010-12345678, his is 025-87654321.'''
pattern = re.compile(r'(\d{3,4})-(\d{7,8})')
index = 0
while True:
matchResult = pattern.search(telNumber, index) # 从指定位置开始匹配
if not matchResult:
break
print('-'*30)
print('Success:')
for i in range(3):
print('Searched content:', matchResult.group(i),
' Start from:', matchResult.start(i),
'End at:', matchResult.end(i),
' Its span is:', matchResult.span(i))
index = matchResult.end(2) # 指定下次匹配的开始位置 '''
------------------------------
Success:
Searched content: 0535-1234567 Start from: 24 End at: 36 Its span is: (24, 36)
Searched content: 0535 Start from: 24 End at: 28 Its span is: (24, 28)
Searched content: 1234567 Start from: 29 End at: 36 Its span is: (29, 36)
------------------------------
Success:
Searched content: 010-12345678 Start from: 47 End at: 59 Its span is: (47, 59)
Searched content: 010 Start from: 47 End at: 50 Its span is: (47, 50)
Searched content: 12345678 Start from: 51 End at: 59 Its span is: (51, 59)
------------------------------
Success:
Searched content: 025-87654321 Start from: 68 End at: 80 Its span is: (68, 80)
Searched content: 025 Start from: 68 End at: 71 Its span is: (68, 71)
Searched content: 87654321 Start from: 72 End at: 80 Its span is: (72, 80)
'''
子模式扩展语法:
(?P<groupname>):为子模式命名
(?iLmsux):设置匹配标志,可以是几个字母的组合,每个字母含义与编译标志相同
(?:...):匹配但不捕获该匹配的子表达式
(?P=groupname):表示在此之前的命名为groupname的子模式
(?#...):表示注释
(?=…):用于正则表达式之后,表示如果=后的内容在字符串中出现则匹配,但不返回=之后的内容
(?!...):用于正则表达式之后,表示如果!后的内容在字符串中不出现则匹配,但不返回!之后的内容
(?<=…):用于正则表达式之前,与(?=…)含义相同
(?<!...):用于正则表达式之前,与(?!...)含义相同