python字符串和正则
python字符串和正则
爱吃窝窝头二.python字符串和正则
[TOC]
字符串无所不在,字符串的处理也是最常见的操作。本章节将总结和字符串处理相关的⼀切操作。主要
包括基本的字符串操作;⾼级字符串操作之正则。⽬前共有 25个小例⼦
1 反转字符串
s = "hello" |
''.join(reversed(s)) |
2 字符串切⽚操作
# 字符串切⽚操作——查找替换3或5的倍数 |
3 join串联字符串
mystr = ['1', |
4 字符串的字节长度
def str_byte_len(mystr): |
str_byte_len('字符') # 6(个字节) |
以下是正则部分
import re |
5 查找第⼀个匹配串
s = 'i love python very much' |
6 查找所有1的索引
s = '昌吉学院信息工程学院B2101班' |
7 \d 匹配数字[0-9]
findall找出全部位置的所有匹配
s = '⼀共20⾏代码运⾏时间13.59s' |
8 匹配浮点数和整数
?表⽰前⼀个字符匹配0或1次
s = '⼀共20⾏代码运⾏时间13.59s' |
# 更好的写法: |
9 ^匹配字符串的开头
s = 'This module provides regular expression matching operations similar to those found in Perl' |
10 re.I 忽略⼤⼩写
s = 'That' |
11 理解compile的作⽤
如果要做很多次匹配,可以先编译匹配串:
import re |
12 使⽤()捕获单词,不想带空格
使⽤ ()捕获
s = 'This module provides regular expression matching operations similar to those found in Perl' |
看到提取单词中未包括第⼀个单词,使⽤ ? 表⽰前⾯字符出现0次或1次,但是此字符还有表⽰贪⼼或⾮
贪⼼匹配含义,使⽤时要谨慎。
pat = r'\s?([a-zA-Z]+)' |
13 split分割单词
使⽤以上⽅法分割单词不是简洁的,仅仅是为了演⽰。分割单词最简单还是使⽤ split函数。
s = 'This module provides regular expression matching operations similar to those found in Perl' |
### 上⾯这句话也可直接使⽤str⾃带的split函数: |
但是,对于风格符更加复杂的情况,split⽆能为⼒,只能使⽤正则
s = 'This,,, module ; \t provides|| regular ; ' |
14 match从字符串开始位置匹配
注意 match, search等的不同: 1. match函数
import re |
- search函数 search是从字符串的任意位置开始匹配
mystr = 'This' |
15 替换匹配的⼦串
sub函数实现对匹配⼦串的替换
content="hello 12345, hello 456321" |
16 贪⼼捕获
(.*)表⽰捕获任意多个字符,尽可能多的匹配字符
content='<h>ddedadsad</h><div>graph</div>bb<div>math</div>cc' |
17 ⾮贪⼼捕获
仅添加⼀个问号( ? ),得到结果完全不同,这是⾮贪⼼匹配,通过这个例⼦体会贪⼼和⾮贪⼼的匹配的
不同。
content='<h>ddedadsad</h><div>graph</div>bb<div>math</div>cc' |
非贪⼼捕获,见好就收。
18 常⽤元字符总结
. 匹配任意字符 |
19 常⽤通⽤字符总结
\s 匹配空⽩字符 |
20 密码安全检查
密码安全要求:1)要求密码为6到20位; 2)密码只包含英⽂字母和数字
pat = re.compile(r'\w{6,20}') # 这是错误的,因为\w通配符匹配的是字母,数字和下划线,题⽬要求不能含有下划线 |
选⽤最保险的 fullmatch⽅法,查看是否整个字符串都匹配:
pat.fullmatch('qaz12') # 返回 None, 长度⼩于6 |
pat.fullmatch('qaz12wsxedcrfvtgb67890942234343434') # None 长度⼤于22 |
pat.fullmatch('qaz_231') # None 含有下划线 |
pat.fullmatch('n0passw0Rd') |
21 爬取百度⾸页标题
import re |
22 批量转化为驼峰格式(Camel)
数据库字段名批量转化为驼峰格式
分析过程
# ⽤到的正则串讲解 |
整理以上分析得到如下代码:
import re |
测试结果:
s = batch_camel(['student_id', 'student\tname', 'student-add']) |
23 str1是否为str2的permutation
排序词(permutation):两个字符串含有相同字符,但字符顺序不同。
from collections import defaultdict |
这个⼩例⼦,使⽤python内置的 defaultdict,默认类型初始化为 int,计数默次数都为0. 这个解法
本质是 hash map lookup
统计出的两个defaultdict:unq_s1,unq_s2,如果相等,就表明str1、 str2互为排序词。
下⾯测试:
r = is_permutation('nice', 'cine') |
以上就是使⽤defaultdict的⼩例⼦
24 str1是否由str2旋转⽽来
stringbook旋转后得到 bookstring,写⼀段代码验证 str1是否为 str2旋转得到。
思路
转化为判断: str1是否为 str2+str2的⼦串
def is_rotation(s1: str, s2: str) -> bool: |
测试
r = is_rotation('stringbook', 'bookstring') |
25 正浮点数
从⼀系列字符串中,挑选出所有正浮点数。
该怎么办?
玩玩正则表达式,⽤正则搞它!
关键是,正则表达式该怎么写呢?
有了!
^[1-9]\d.\d$
^ 表⽰字符串开始
[1-9] 表⽰数字1,2,3,4,5,6,7,8,9
^[1-9] 连起来表⽰以数字 1-9 作为开头
\d 表⽰⼀位 0-9 的数字
‘*’ 表⽰前⼀位字符出现 0 次,1 次或多次
\d* 表⽰数字出现 0 次,1 次或多次
. 表⽰⼩数点
$ 表⽰字符串以前⼀位的字符结束
^[1-9]\d.\d$ 连起来就求出所有⼤于 1.0 的正浮点数。
那 0.0 到 1.0 之间的正浮点数,怎么求,⼲嘛不直接汇总到上⾯的正则表达式中呢?
这样写不⾏吗: ^[0-9]\d.\d$
OK!
那我们⽴即测试下呗
import re |
结果显⽰,正则表达式 ^[0-9]\d.\d$ 竟然匹配到 000.2,认为它是⼀个正浮点数~~~!!!!
晕!!!!!!
所以知道为啥要先匹配⼤于 1.0 的浮点数了吧!
如果能写出这个正则表达式,再写另⼀部分就不困难了!
0.0 到 1.0 间的浮点数: ^0.\d*[1-9]\d*$
两个式⼦连接起来就是最终的结果:
^[1-9]\d.\d|0.\d*[1-9]\d*$
如果还是看不懂,看看下⾯的正则分布剖析图吧: