Python字符串和正则

  • 先导入包
  • 1. 查找匹配串
  • 2. \d 匹配浮点数 数字[0-9]
  • 3. ^匹配字符串的开头,忽略大小写
  • 4. \W 和 \w 的用法
  • 5. match从固定位置匹配
  • 6. 替换匹配的子串
  • 7. 贪心捕获(.*)表示捕获任意多个字符,尽可能多的匹配字符
  • 8. 密码安全检查
  • 9. 批量转化为驼峰格式(Camel)
  • 10. str1是否为str2的排序词(permutation)
  • 11. str1是否由str2旋转而来
  • 12 . 了解正则浮点数


常用元字符总结
	. 匹配任意字符
	^ 匹配字符串开始位置
	$ 匹配字符串中结束的位置
	* 前面的原子重复0次、1次、多次
	? 前面的原子重复0次或者1次
	+ 前面的原子重复1次或多次
	{n} 前面的原子出现了 n 次
	{n,} 前面的原子至少出现 n 次
	{n,m} 前面的原子出现次数介于 n-m 之间
	( ) 分组,需要输出的部分
常用通用字符总结
	\s	匹配空白字符
	\w	匹配任意字母/数字/下划线
	\W	和小写 w 相反,匹配任意字母/数字/下划线以外的字符
	\d	匹配十进制数字
	\D	匹配除了十进制数以外的值[0-9]	匹配一个0-9之间的数字[a-z]	匹配小写英文字母
	[A-Z]	匹配大写英文字母

先导入包

import re
from IPython.core.interactiveshell import InteractiveShell
InteractiveShell.ast_node_interactivity = "all" # 显示所有结果

1. 查找匹配串

# 1 找第一个pat的索引
s = 'i love python2.7 and python3.6 1 23'
pat1 = 'py'
r1 = re.search(pat,s) 
print(r1.span())  # 只显示出第一个搜索到的地址

# 2.查找所有pat的索引
r2 = re.finditer(pat1,s) 
for i in r2:
    print(i)

python re正则获取指定字符串存在的一行数据 python 正则 匹配任意字符串_字符串

2. \d 匹配浮点数 数字[0-9]

#  findall 找出全部位置的所有匹配
s = 'I say:"1,2,3,3,2,1,0.52,0.33,0.1,0 over"'
pat = r'\d+' # +表示匹配数字(\d表示数字的通用字符)1次或多次
r3 = re.findall(pat,s)
print(r3)

# 匹配浮点数和整数,?表示前一个字符匹配0或1次
pat = r'\d+\.\d+|\d+' # A|B,匹配A失败才匹配B
r4 = re.findall(pat,s)
print(r4)

python re正则获取指定字符串存在的一行数据 python 正则 匹配任意字符串_子串_02

3. ^匹配字符串的开头,忽略大小写

# ^匹配字符串的开头
s = 'email for me is 1967807143@qq.com'
r5 = re.findall('^[em].*',s)# 匹配以e,m开始的字符串,后面是多个任意字符
print(r5)

pat = r'^[TME]' # 以T,M,E开头的字符串
r6 = re.findall(pat,s) # 因字符串的开头是`e`,不在匹配范围内,所以返回为空

#  re.I 忽略大小写
r7 = re.findall(pat, s, re.I) # 忽略大小写后可以找到T
print(r6, r7)

python re正则获取指定字符串存在的一行数据 python 正则 匹配任意字符串_字符串_03

4. \W 和 \w 的用法

import re

def digital_chars(s):
     # \W 匹配不是数字和字母的字符
    pat1 = re.compile('\W+')
    special_chars = pat1.findall(s) 
    if special_chars:
        print(f'特殊字符:{special_chars}')
     
     # \w 匹配任意字母/数字/下划线
    pat2 = re.compile('\w')
    digital = pat2.findall(s)
    if digital:
        print(f'非特殊字符:{digital}')
    
    return
digital_chars('!s#2@edc')

python re正则获取指定字符串存在的一行数据 python 正则 匹配任意字符串_子串_04

5. match从固定位置匹配

def match(s):
    pat = re.compile('of')
    r1 = pat.match(s,7) # None
    r2 = pat.match(s,8) # 从固定位置处开始匹配
    print(r1,'\n',r2)
    return

s = 'the man of strength is of imporatace'
match(s)

6. 替换匹配的子串

# sub 函数实现对匹配子串的替换
def replace(data, up_data):
#   pat = re.compile(r'\d+')   # 要替换数字的部分
    pat = re.compile(r'\D+')   # 要替换非数字的部分
    d = pat.sub(up_data, data)
    print(d)
    
data = 'hello 118, hi 007'
# up_data = '0000'  # 替换数字
up_data = ' 你是?' # 替换非数字
replace(data, up_data)

python re正则获取指定字符串存在的一行数据 python 正则 匹配任意字符串_字符串_05

7. 贪心捕获(.*)表示捕获任意多个字符,尽可能多的匹配字符

def greed_capture(content):
    pat1 = re.compile(r"<div>(.*)</div>") # 贪婪模式
    m1 = pat1.findall(content)
    print(m1)
    
    # 非贪心捕获 仅添加一个问号( ? )
    pat2 = re.compile(r"<div>(.*?)</div>")
    m2 = pat2.findall(content)
    print(m2)
    
content = '<h>ddedadsad</h><div> graph</div> bb<div> math</div>cc' 
greed_capture(content)

python re正则获取指定字符串存在的一行数据 python 正则 匹配任意字符串_字符串_06

8. 密码安全检查

密码安全要求:

  1. 要求密码为6到20位;
  2. 密码只包含英文字母和数字
# 使用最稳的方法:\da-zA-Z满足`密码只包含英文字母和数字` 
def password(s):
    pat = re.compile(r'[\da-zA-Z]{6,20}')
    judge = pat.fullmatch(s)
    if judge:
        print(judge)
    else:
        print("密码错误,请重新输入")
    
print("请输入6到20位且只包含英文字母和数字的密码:")
for i in range(3):
    s = input()
    password(s)

python re正则获取指定字符串存在的一行数据 python 正则 匹配任意字符串_字符串_07

import re
from urllib import request
def web_title(web):
    # 爬虫爬取百度首页内容
    data=request.urlopen(web).read().decode()
    
    # 分析网页,确定正则表达式
    pat=r'<title>(.*?)</title>'
    result=re.search(pat,data)
    print(result.group())
    print(result)
    
web = "http://www.baidu.com/"
web_title(web)

python re正则获取指定字符串存在的一行数据 python 正则 匹配任意字符串_子串_08

9. 批量转化为驼峰格式(Camel)

用到的正则串讲解

  1. \s 指匹配: [ \t\n\r\f\v] # A|B:表示匹配A串或B串
  2. re.sub(pattern, newchar, string)
  3. 用newchar字符替代与pattern匹配的字符所有


import re 
def camel(s):
    s = re.sub(r"(\s|_|-)+", " ", s).title().replace(" ", "") 
    return s[0].lower() + s[1:] # 第一个变小写

# 批量转化
def batch_camel(slist): # 循环调用camel函数
    return [camel(s) for s in slist]

s = batch_camel(['student_id', 'student\tname', 'student-add', 'Student\n-class']) 
print(s)

python re正则获取指定字符串存在的一行数据 python 正则 匹配任意字符串_字符串_09

10. str1是否为str2的排序词(permutation)

排序词 (permutation):两个字符串含有相同字符,但字符顺序不同。

  1. 先判断是否None,再判断len相等不;
  2. 把词的每个字母保存到字典,这样才能判断两个字符串是否含有相同字符。用 defaultdict() 方法。python内置的 defaultdict ,默认类型初始化为int ,计数默次数都为0;
  3. 最后 return 返回结果值。
from collections import defaultdict

def is_permutation(str1, str2):
    if str1 is None or str2 is None:
        return False
    
    if len(str1) != len(str2): 
        return False
    
    s1 = defaultdict(int) 
    s2 = defaultdict(int)
#     print(s1,s2)
    
    for c1 in str1:
        s1[c1] += 1 
        
    for c2 in str2:
        s2[c2] += 1
    
    print(s1,"\n",s2)
    return s1 == s2 # 值赋给r

r = is_permutation('nice import ', 'port im cine') 
print(r)

python re正则获取指定字符串存在的一行数据 python 正则 匹配任意字符串_字符串_10

11. str1是否由str2旋转而来

逻辑:判断 str1 是否为str2+str2 的子串stringbook => bookstring ,stringbook 是 bookstringbookstring 字串。

def is_rotation(s1: str, s2: str) -> bool: # ①r 代入,返回True
    if s1 is None or s2 is None:
        return False
    if len(s1) != len(s2):
        return False
        
	# ②按顺序执行
    def is_substring(s1: str, s2: str) -> bool: 
        return s1 in s2
        # ③第一次 False
        # ⑤第二次 Ture
    
    return is_substring(s1, s2 + s2) # ④再调用上面方法
    # ⑥ return 把True返回给r

r = is_rotation('stringbook', 'bookstring') 
print(r)

python re正则获取指定字符串存在的一行数据 python 正则 匹配任意字符串_字符串_11

12 . 了解正则浮点数

^[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.0 到 1.0 之间的正浮点数不可以: ^[0-9]\d*\.\d*$,会出现如下图情况。

python re正则获取指定字符串存在的一行数据 python 正则 匹配任意字符串_字符串_12


0.0 到 1.0 间的浮点数: ^0\.\d*[1-9]\d*$ 以0. 开头的数字。

两个式子连接起来就是:^[1-9]\d*\.\d*|0\.\d*[1-9]\d*$