Python正则表达式


Python 正则表达式(Regular Expression)是一种用于匹配、查找、替换字符串的强大模式语言,通过特殊的语法规则定义字符串的匹配模式,广泛应用于文本验证(如邮箱、手机号)、信息提取(如从文本中抓取值)、字符串替换等场景。Python 中通过内置的 re 模块提供对正则表达式的支持。

一、正则表达式的核心概念

正则表达式本质是一个字符串模式,用于描述“什么样的字符串符合规则”。例如,模式 r"^\d{3}-\d{8}$" 可匹配“010-12345678”这样的固定电话格式。

  • 元字符:正则表达式中具有特殊含义的字符(如 .*+ 等),是构建模式的核心。
  • 普通字符:除元字符外的字符(如字母、数字、空格),仅匹配自身。

二、正则表达式基本语法(元字符)

掌握元字符是学习正则的基础,以下是常用元字符及含义:

1. 字符匹配

元字符 含义 示例 匹配结果
. 匹配任意单个字符(除换行符 \n a.c abca1ca&c
[] 匹配括号内的任意单个字符 a[0-9]c a0ca5c(0-9的数字)
[^] 匹配不在括号内的任意单个字符 a[^0-9]c abca&c(非数字)
\d 匹配任意数字(等价于 [0-9] a\d a1a9
\D 匹配任意非数字(等价于 [^0-9] a\D aaa!
\w 匹配字母、数字、下划线[a-zA-Z0-9_] \w\w ab12a_
\W 匹配非字母、数字、下划线 \W\W !!@#
\s 匹配空白字符(空格、\t\n等) a\sb a ba\tb(a和b之间有空白)
\S 匹配非空白字符 a\Sb a1ba@b

2. 数量限定(修饰前一个字符的出现次数)

元字符 含义 示例 匹配结果
* 前一个字符出现0次或多次(贪婪匹配) ab* a(b出现0次)、ababb
+ 前一个字符出现1次或多次(贪婪匹配) ab+ ababb(至少1个b)
? 前一个字符出现0次或1次 ab? aab(最多1个b)
{n} 前一个字符恰好出现n次 a{2} aa(刚好2个a)
{n,} 前一个字符出现至少n次 a{2,} aaaaa(≥2个a)
{n,m} 前一个字符出现n到m次(含n和m) a{1,3} aaaaaa

3. 边界匹配(限定字符串的位置)

元字符 含义 示例 匹配结果
^ 匹配字符串开头(多行模式下匹配每行开头) ^abc abc(字符串以abc开头)
$ 匹配字符串结尾(多行模式下匹配每行结尾) abc$ abc(字符串以abc结尾)
\b 匹配单词边界(单词与非单词的交界) \bhello\b hello(独立单词,如 hello! 中的hello)
\B 匹配非单词边界 \Bhello\B xhelloy 中的 hello(被单词字符包围)

4. 逻辑与分组

元字符 含义 示例 匹配结果
| 逻辑“或”,匹配两边任意一个模式 abc|def abcdef
() 分组,将括号内的模式视为一个整体 (ab)+ ababab(ab重复1次或多次)
\num 引用第num个分组的匹配结果(num为1开始的整数) (a)\1 aa(第一个分组匹配a,\1引用该结果)

5. 贪婪与非贪婪匹配

  • 贪婪匹配:默认行为,尽可能匹配最长的字符串(如 *+{n,m})。
  • 非贪婪匹配:在数量限定符后加 ?,尽可能匹配最短的字符串

示例:

import re

text = "aabbaabb"
# 贪婪匹配:.* 尽可能匹配最长的字符串(从第一个a到最后一个b)
print(re.match(r"a.*b", text).group())  # → "aabbaabb"

# 非贪婪匹配:.*? 尽可能匹配最短的字符串(从第一个a到第一个b)
print(re.match(r"a.*?b", text).group())  # → "aabb"

三、Python re 模块常用函数

re 模块提供了一系列函数用于正则匹配,核心函数如下:

1. re.match(pattern, string, flags=0)

  • 功能:从字符串开头匹配模式,若开头不匹配则返回 None
  • 返回值:匹配对象(Match),若匹配失败返回 None
  • 示例
import re

# 匹配以"hello"开头的字符串
result = re.match(r"hello", "hello world")
print(result.group())  # → "hello"(匹配成功,返回匹配内容)

# 开头不匹配,返回None
result = re.match(r"world", "hello world")
print(result)  # → None

2. re.search(pattern, string, flags=0)

  • 功能:在整个字符串中查找第一个匹配(不限于开头),找到则返回匹配对象,否则返回 None
  • 区别于 matchmatch 仅从开头匹配,search 搜索整个字符串。
  • 示例
# 在字符串中查找"world"(不在开头)
result = re.search(r"world", "hello world")
print(result.group())  # → "world"

3. re.findall(pattern, string, flags=0)

  • 功能:在字符串中查找所有匹配,返回包含所有匹配内容的列表(无匹配则返回空列表)。
  • 示例
# 提取字符串中所有数字
text = "age: 18, score: 95, weight: 60"
nums = re.findall(r"\d+", text)  # \d+ 匹配1个或多个数字
print(nums)  # → ['18', '95', '60']

4. re.finditer(pattern, string, flags=0)

  • 功能:与 findall 类似,但返回迭代器(每个元素是 Match 对象),适合处理大量匹配结果(节省内存)。
  • 示例
text = "a1 b2 c3"
matches = re.finditer(r"\d", text)  # 查找所有单个数字
for m in matches:
    print(m.group())  # 依次输出:1、2、3

5. re.sub(pattern, repl, string, count=0, flags=0)

  • 功能:用 repl 替换字符串中所有匹配 pattern 的子串,返回替换后的新字符串。
  • 参数:count 为最大替换次数(默认0表示全部替换)。
  • 示例
# 将所有数字替换为"*"
text = "a1 b2 c3"
new_text = re.sub(r"\d", "*", text)
print(new_text)  # → "a* b* c*"

# 只替换前2个数字
new_text2 = re.sub(r"\d", "*", text, count=2)
print(new_text2)  # → "a* b* c3"

6. re.split(pattern, string, maxsplit=0, flags=0)

  • 功能:按匹配 pattern 的子串分割字符串,返回分割后的列表。
  • 参数:maxsplit 为最大分割次数(默认0表示全部分割)。
  • 示例
# 按逗号或空格分割字符串
text = "a,b c,d"
parts = re.split(r"[, ]", text)  # 匹配逗号或空格
print(parts)  # → ['a', 'b', 'c', 'd']

7. re.compile(pattern, flags=0)

  • 功能:编译正则表达式模式为正则对象RegexObject),可重复使用(提高效率,尤其多次匹配时)。
  • 示例
# 编译模式(只做一次)
pattern = re.compile(r"\d+")

# 重复使用编译后的对象
print(pattern.findall("age: 18"))  # → ['18']
print(pattern.findall("score: 95"))  # → ['95']

四、分组与捕获(() 的用法)

() 用于将模式分组,可通过匹配对象的 group() 方法提取分组内容:

  • group(0)group():返回整个匹配内容。
  • group(1)group(2)...:返回第1、2...个分组的内容。

示例:提取邮箱中的用户名和域名

import re

email = "user@example.com"
# 分组匹配:(用户名)@(域名)
pattern = r"(\w+)@(\w+\.\w+)"
result = re.match(pattern, email)

print(result.group(0))  # 整个匹配 → "user@example.com"
print(result.group(1))  # 第一个分组(用户名)→ "user"
print(result.group(2))  # 第二个分组(域名)→ "example.com"
print(result.groups())  # 所有分组组成的元组 → ("user", "example.com")

五、常用修饰符(flags 参数)

修饰符用于改变正则匹配的行为,常用值:

  • re.IGNORECASEre.I):忽略大小写匹配。
  • re.DOTALLre.S):让 . 匹配包括换行符 \n 在内的所有字符。
  • re.MULTILINEre.M):让 ^$ 匹配每行的开头和结尾(而非整个字符串)。

示例:忽略大小写匹配

import re

# 不忽略大小写:无法匹配大写的Hello
print(re.match(r"hello", "Hello"))  # → None

# 忽略大小写:成功匹配
print(re.match(r"hello", "Hello", flags=re.IGNORECASE).group())  # → "Hello"

六、实际应用场景

1. 验证手机号(中国大陆手机号:11位数字,以1开头)

def is_valid_phone(phone):
    pattern = r"^1\d{10}$"  # ^1:以1开头;\d{10}:10个数字;$:结尾
    return bool(re.match(pattern, phone))

print(is_valid_phone("13812345678"))  # → True
print(is_valid_phone("1234567890"))   # → False(不足11位)

2. 提取HTML中的所有链接(<a href="url">

html = '''
<a href="https://www.baidu.com">百度</a>
<a href="https://www.google.com">谷歌</a>
'''
# 分组提取href的值(""中的内容)
urls = re.findall(r'href="(.*?)"', html)  # .*? 非贪婪匹配,避免匹配到多个链接
print(urls)  # → ['https://www.baidu.com', 'https://www.google.com']

3. 清洗文本(去除所有标点符号)

import string

text = "Hello, World! It's a test."
# 匹配所有标点符号(string.punctuation包含所有标点)
clean_text = re.sub(rf"[{string.punctuation}]", "", text)
print(clean_text)  # → "Hello World Its a test"

七、注意事项

1.转义字符:若需匹配元字符本身(如 .*),需用 \ 转义(如 \. 匹配 .)。

# 匹配IP地址中的点(需转义)
print(re.match(r"192\.168\.1\.1", "192.168.1.1").group())  # → "192.168.1.1"

2.原始字符串:正则模式建议用原始字符串(r"模式"),避免 \ 被Python解释器转义(如 r"\d" 正确表示 \d,而非 d)。

3.性能问题:复杂的正则表达式可能效率较低,尤其是处理大文本时,建议:

  • re.compile 编译模式复用。
  • 避免过度使用贪婪匹配(必要时用非贪婪)。

总结

正则表达式是处理字符串的强大工具,Python 的 re 模块提供了完整支持。核心知识点包括:

  • 元字符:字符匹配、数量限定、边界匹配、分组等。
  • 常用函数:match(开头匹配)、search(全局首匹配)、findall(所有匹配)、sub(替换)等。
  • 分组:通过 () 提取子串,灵活获取关键信息。

掌握正则表达式能极大提升文本处理效率,建议结合实际场景(如验证、提取、清洗)多练习,逐步熟悉元字符的组合使用。

正则表达式

正则表达式这东西,你说它简单它也简单,你说它难吧,确实不容易。为什么?这东西就是死记硬背的。背过了相关的语法,使用起来就so easy。但记不熟语法,就犯难了。

正则表达式简介

正则表达式,是一个特殊的字符序列,又称规则表达式(英语:Regular Expression,在代码中常简写为regex、regexp 或RE),本质而言是一种小型的,高度专业化的编程语言。 Python 自1.5版本起增加了re 模块,re 模块使Python语言拥有全部的正则表达式功能。

正则语法表

这个你背不过,再好的教程看了也没用。如何巧记?我们需要对其进行分类。

  • 开头结尾

这一对标签,大家都不会陌生…

模式 描述
^ 从整个字符串开头的地方匹配
$ 从整个字符串的结尾开始匹配
  • 模糊匹配
模式 描述
. 匹配任意字符,除了换行符
? 重复匹配?号前面0个或1个由前面的正则表达式定义的片段,非贪婪方式(?写在数量词的之后)
* 重复匹配*号前面0个或多个的表达式。{0, 无穷大}
+ 重复匹配+号前面1个或多个的表达式。{1,无穷大}
a丨b 匹配a或b
  • 关于括号
模式 描述
{} 表示匹配"{}"前边的字符 指定个数为"{}"里边的数值{最小此时,最大次数}
[] 表示一个字符集,它常被用来指定一个字符类别,字符可以单个列出,也可以用“-”号分隔的两个给定字符来表示一个字符区间
() 分组 将括号中的内容 当作整体来对待
  • \ 反斜杠的应用
模式 描述
\w 匹配字母数字及下划线
\W 匹配非字母数字及下划线
\s 匹配任意空白字符,等价于 [\t\n\r\f].
\S 匹配任意非空字符
\d 匹配任意数字,等价于 [0-9].
\D 匹配任意非数字
\A 匹配字符串开始^
\Z 匹配字符串结束,如果是存在换行,只匹配到换行前的结束字符串。$
\z 匹配字符串结束
\G 匹配最后匹配完成的位置。
\b 匹配一个单词边界,也就是指单词和空格间的位置。例如, 'er\b' 可以匹配"never" 中的 'er',但不能匹配 "verb" 中的 'er'。
\B 匹配非单词边界。'er\B' 能匹配 "verb" 中的 'er',但不能匹配 "never" 中的 'er'。
\n, \t, 等. 匹配一个换行符。匹配一个制表符。等
\1…\9 匹配第n个分组的内容。
\10 匹配第n个分组的内容,如果它经匹配。否则指的是八进制字符码的表达式。
  • 其他
模式 描述
(?imx) 正则表达式包含三种可选标志:i, m, 或 x 。只影响括号中的区域。
(?-imx) 正则表达式关闭 i, m, 或 x 可选标志。只影响括号中的区域。
(?: re) 类似 (…), 但是不表示一个组
(?imx: re) 在括号中使用i, m, 或 x 可选标志
(?-imx: re) 在括号中不使用i, m, 或 x 可选标志
(?#…) 注释. (?# 正则中的注释)
(?= re) 前向肯定界定符。如果所含正则表达式,以 … 表示,在当前位置成功匹配时成功,否则失败。但一旦所含表达式已经尝试,匹配引擎根本没有提高;模式的剩余部分还要尝试界定符的右边。
(?! re) 前向否定界定符。与肯定界定符相反;当所含表达式不能在字符串当前位置匹配时成功
(?> re) 匹配的独立模式,省去回溯。

re模块用法

re.(function)(pattern[, flags]) pattern : 一个字符串形式的正则表达式 flags : 可选,表示匹配模式,比如忽略大小写,多行模式等,具体参数为:

  1. re.I 忽略大小写
  2. re.L 表示特殊字符集 \w, \W, \b, \B, \s, \S 依赖于当前环境
  3. re.M 多行模式
  4. re.S 即为 . 并且包括换行符在内的任意字符(. 不包括换行符)
  5. re.U 表示特殊字符集 \w, \W, \b, \B, \d, \D, \s, \S 依赖于 Unicode 字符属性数据库
  6. re.X 为了增加可读性,忽略空格和 # 后面的注释
  • findall() (即:全部找到,返回的是一个列表)

findall(string[, pos[, endpos]]) 参数:

  1. string : 待匹配的字符串。
  2. pos : 可选参数,指定字符串的起始位置,默认为 0。
  3. endpos : 可选参数,指定字符串的结束位置,默认为字符串的长度。
import re
s = 'helloworld hellobeijing'
ret = re.findall('hello\S+',s)
print(ret)
['helloworld', 'hellobeijing']
  • finditer()

和 findall 类似,在字符串中找到正则表达式所匹配的所有子串,并把它们作为一个迭代器返回。 re.finditer(pattern, string, flags=0) 参数:

参数 描述
pattern 匹配的正则表达式
string 要匹配的字符串。
flags 标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等
  • search() 与 match()

相同点:

  1. 语法:re.search/match(pattern, string, flags=0)
  2. 函数参数说明:
参数 描述
pattern 匹配的正则表达式
string 要匹配的字符串。
flags 标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等
  1. 可以使用group(num) 或 groups() 匹配对象函数来获取匹配表达式。
匹配方法 描述
group(num=0) 匹配的整个表达式的字符串,group() 可以一次输入多个组号,在这种情况下它将返回一个包含那些组所对应值的元组
groups() 返回一个包含所有小组字符串的元组,从 1 到 所含的小组号
start([group]) 方法用于获取分组匹配的子串在整个字符串中的起始位置(子串第一个字符的索引),参数默认值为 0
end([group]) 方法用于获取分组匹配的子串在整个字符串中的结束位置(子串最后一个字符的索引+1),参数默认值为 0
span([group]) 方法返回 (start(group), end(group)
import re
# re.search
ret = re.search('h..','hello hello world')
print(ret) # 输出结果:<_sre.SRE_Match object; span=(0, 3), match='hel'>
ret1 = re.search('h..','hello hello world').group()
print(ret1) # 输出结果:hel 只输出第一个符合条件的结果

# re.match
ret = re.match('asd','asdhskdjfksji')
print(ret) # 输出结果:<_sre.SRE_Match object; span=(0, 3), match='asd'>返回的是一个对象。
ret1 = re.match('asd','asdhskdjfasdksjiasd').group()
print(ret1) # 输出结果:asd 调用.group()方法,只返回匹配的第一个结果。

不同点:

  1. re.match只匹配字符串的开始,如果字符串开始不符合正则表达式,则匹配失败,函数返回None
  2. re.search匹配整个字符串,直到找到一个匹配
# re.search
s = 'helloworld hellobeijing'
ret = re.search('hellob\S+',s)
print(ret)
<re.Match object; span=(11, 23), match='hellobeijing'>

# re.match
s = 'helloworld hellobeijing'
ret = re.match('hellob\S+',s)
print(ret)
None
  • split() 分隔符 对比字符串里边的split方法。

split 方法按照能够匹配的子串将字符串分割后返回列表,它的使用形式如下:

re.split(pattern, string[, maxsplit=0, flags=0])

参数 描述
pattern 匹配的正则表达式
string 要匹配的字符串。
maxsplit 分隔次数,maxsplit=1 分隔一次,默认为 0,不限制次数。
flags 标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。参见:正则表达式修饰符 - 可选标志
import re
s = 'helloworld hellobeijing'
ret = re.split('hello',s)
print(ret)
['', 'world ', 'beijing']
  • sub() 替换;类似字符串中的replace()方法。

re.sub用于替换字符串中的匹配项。 语法: re.sub(pattern, repl, string, count=0, flags=0) 参数:

  1. pattern : 正则中的模式字符串。
  2. repl : 替换的字符串,也可为一个函数。
  3. string : 要被查找替换的原始字符串。
  4. count : 模式匹配后替换的最大次数,默认 0 表示替换所有的匹配。
import re
s = 'helloworld hellobeijing'
ret = re.sub('hello','goodbye',s)
print(ret)
goodbyeworld goodbyebeijing
  • compile(strPattern[,flag]): 这个方法是Pattern类的工厂方法,用于将字符串形式的正则表达式编译为Pattern对象

compile 函数用于编译正则表达式,生成一个正则表达式( Pattern )对象,供 match() 和 search() 这两个函数使用。 语法格式为: re.compile(pattern[, flags]) 参数: pattern : 一个字符串形式的正则表达式

  1. flags : 可选,表示匹配模式,比如忽略大小写,多行模式等,具体参数为:
  2. re.I 忽略大小写
  3. re.L 表示特殊字符集 \w, \W, \b, \B, \s, \S 依赖于当前环境
  4. re.M 多行模式
  5. re.S 即为 . 并且包括换行符在内的任意字符(. 不包括换行符)
  6. re.U 表示特殊字符集 \w, \W, \b, \B, \d, \D, \s, \S 依赖于 Unicode 字符属性数据库
  7. re.X 为了增加可读性,忽略空格和 # 后面的注释
import re
pattern = re.compile('he.{3}')
pattern.match(s)
<re.Match object; span=(0, 5), match='hello'>

正则练习

import re

1 查找第一个匹配串

s = 'i love python very much'
pat = 'python' 
r = re.search(pat,s)
print(r.span()) #(7,13)

2 查找所有1

s = '山东省潍坊市青州第1中学高三1班'
pat = '1'
r = re.finditer(pat,s)
for i in r:
    print(i)

# <re.Match object; span=(9, 10), match='1'>
# <re.Match object; span=(14, 15), match='1'>

3 \d匹配数字[0-9]

s = '一共20行代码运行时间13.59s'
pat = r'\d+' # +表示匹配数字(\d表示数字的通用字符)1次或多次
r = re.findall(pat,s)
print(r)
# ['20', '13', '59']

我们想保留13.59而不是分开,请看4

4 ?表示前一个字符匹配0或1次

s = '一共20行代码运行时间13.59s'
pat = r'\d+\.?\d+' # ?表示匹配小数点(\.)0次或1次
r = re.findall(pat,s)
print(r)
# ['20', '13.59']

5 ^匹配字符串的开头

s = 'This module provides regular expression matching operations similar to those found in Perl'
pat = r'^[emrt]' # 查找以
r = re.findall(pat,s)
print(r)
# [],因为字符串的开头是字符`T`,不在emrt匹配范围内,所以返回为空

6 re.I 忽略大小写

s = 'This module provides regular expression matching operations similar to those found in Perl'
pat = r'^[emrt]' # 查找以
r = re.compile(pat,re.I).search(s)
print(r)
# <re.Match object; span=(0, 1), match='T'> 表明字符串的开头在匹配列表中

7 使用正则提取单词

这是不准确版本,请参看第9个

s = 'This module provides regular expression matching operations similar to those found in Perl'
pat = r'\s[a-zA-Z]+'  
r = re.findall(pat,s)
print(r) #[' module', ' provides', ' regular', ' expression', ' matching', ' operations', ' similar', ' to', ' those', ' found', ' in', ' Perl']

8 只捕获单词,去掉空格

使用()捕获,这是不准确版本,请参看第9个

s = 'This module provides regular expression matching operations similar to those found in Perl'
pat = r'\s([a-zA-Z]+)'  
r = re.findall(pat,s)
print(r) #['module', 'provides', 'regular', 'expression', 'matching', 'operations', 'similar', 'to', 'those', 'found', 'in', 'Perl']

9 补充上第一个单词

上面第8,看到提取单词中未包括第一个单词,使用?表示前面字符出现0次或1次,但是此字符还有表示贪心或非贪心匹配含义,使用时要谨慎。

s = 'This module provides regular expression matching operations similar to those found in Perl'
pat = r'\s?([a-zA-Z]+)'  
r = re.findall(pat,s)
print(r) #['This', 'module', 'provides', 'regular', 'expression', 'matching', 'operations', 'similar', 'to', 'those', 'found', 'in', 'Perl']

10 使用split函数直接分割单词

使用以上方法分割单词,不是简洁的,仅仅为了演示。分割单词最简单还是使用split函数。

s = 'This module provides regular expression matching operations similar to those found in Perl'
pat = r'\s+'  
r = re.split(pat,s)
print(r) # ['This', 'module', 'provides', 'regular', 'expression', 'matching', 'operations', 'similar', 'to', 'those', 'found', 'in', 'Perl']

11 提取以m或t开头的单词,忽略大小写

下面出现的结果不是我们想要的,原因出在 ?上!

s = 'This module provides regular expression matching operations similar to those found in Perl'
pat = r'\s?([mt][a-zA-Z]*)' # 查找以
r = re.findall(pat,s)
print(r) # ['module', 'matching', 'tions', 'milar', 'to', 'those']

12 使用^查找字符串开头的单词

综合11和12得到所有以m或t开头的单词

s = 'This module provides regular expression matching operations similar to those found in Perl'
pat = r'^([mt][a-zA-Z]*)\s' # 查找以
r = re.compile(pat,re.I).findall(s)
print(r) # ['This']

13 先分割,再查找满足要求的单词

使用match表示是否匹配

s = 'This module provides regular expression matching operations similar to those found in Perl'
pat = r'\s+'  
r = re.split(pat,s)
res = [i for i in r if re.match(r'[mMtT]',i)] 
print(res) # ['This', 'module', 'matching', 'to', 'those']

14 贪心匹配

尽可能多的匹配字符

content='<h>ddedadsad</h><div>graph</div>bb<div>math</div>cc'
pat=re.compile(r"<div>(.*)</div>")  #贪婪模式
m=pat.findall(content)
print(m) # ['graph</div>bb<div>math']

15 非贪心匹配

与14相比,仅仅多了一个问号(?),得到结果完全不同。

content='<h>ddedadsad</h><div>graph</div>bb<div>math</div>cc'
pat=re.compile(r"<div>(.*?)</div>")  #贪婪模式
m=pat.findall(content)
print(m) # ['graph', 'math']

与14比较可知,贪心匹配和非贪心匹配的区别,后者是字符串匹配后立即返回,见好就收。

16 含有多种分割符

使用split函数

content = 'graph math,,english;chemistry' # 这种
pat=re.compile(r"[\s\,\;]+")  #贪婪模式
m=pat.split(content)
print(m) # ['graph', 'math', 'english', 'chemistry']

17 替换匹配的子串

sub函数实现对匹配子串的替换

content="hello 12345, hello 456321"    
pat=re.compile(r'\d+') #要替换的部分
m=pat.sub("666",content)
print(m) # hello 666, hello 666

18 爬取百度首页标题

import re
from urllib import request

#爬虫爬取百度首页内容
data=request.urlopen("http://www.baidu.com/").read().decode()

#分析网页,确定正则表达式
pat=r'<title>(.*?)</title>'

result=re.search(pat,data)
print(result) <re.Match object; span=(1358, 1382), match='<title>百度一下,你就知道</title>'>

result.group() # 百度一下,你就知道

19 常用元字符总结复习

. 匹配任意字符  
^ 匹配字符串始位置 
$ 匹配字符串中结束的位置 
* 前面的原子重复0次1次多次 
? 前面的原子重复一次或者0次 
+ 前面的原子重复一次或多次
{n} 前面的原子出现了 n 次
{n,} 前面的原子至少出现 n 次
{n,m} 前面的原子出现次数介于 n-m 之间
( ) 分组,需要输出的部分

20 常用通用字符总结复习

\s  匹配空白字符 
\w  匹配任意字母/数字/下划线 
\W  和小写 w 相反,匹配任意字母/数字/下划线以外的字符
\d  匹配十进制数字
\D  匹配除了十进制数以外的值 
[0-9]  匹配一个0-9之间的数字
[a-z]  匹配小写英文字母
[A-Z]  匹配大写英文字母

最全的常用正则表达式大全

一、校验数字的表达式

  • 数字:^[0-9]*$
  • n位的数字:^\d{n}$
  • 至少n位的数字:^\d{n,}$
  • m-n位的数字:^\d{m,n}$
  • 零和非零开头的数字:^(0|[1-9][0-9]*)$
  • 非零开头的最多带两位小数的数字:^([1-9][0-9]*)+(.[0-9]{1,2})?$
  • 带1-2位小数的正数或负数:^(-)?\d+(.\d{1,2})?$
  • 正数、负数、和小数:^(-|+)?\d+(.\d+)?$
  • 有两位小数的正实数:^[0-9]+(.[0-9]{2})?$
  • 有1~3位小数的正实数:^[0-9]+(.[0-9]{1,3})?$
  • 非零的正整数:^[1-9]\d$ 或 ^([1-9][0-9]){1,3}$ 或 ^+?[1-9][0-9]*$
  • 非零的负整数:^-[1-9][]0-9″$ 或 ^-[1-9]\d$
  • 非负整数:^\d+$ 或 ^[1-9]\d*|0$
  • 非正整数:^-[1-9]\d*|0$ 或 ^((-\d+)|(0+))$
  • 非负浮点数:^\d+(.\d+)?$ 或 ^[1-9]\d.\d|0.\d[1-9]\d|0?.0+|0$
  • 非正浮点数:^((-\d+(.\d+)?)|(0+(.0+)?))$ 或 ^(-([1-9]\d.\d|0.\d[1-9]\d))|0?.0+|0$
  • 正浮点数:^[1-9]\d.\d|0.\d[1-9]\d$ 或 ^(([0-9]+.[0-9][1-9][0-9])|([0-9][1-9][0-9].[0-9]+)|([0-9][1-9][0-9]))$
  • 负浮点数:^-([1-9]\d.\d|0.\d[1-9]\d)$ 或 ^(-(([0-9]+.[0-9][1-9][0-9])|([0-9][1-9][0-9].[0-9]+)|([0-9][1-9][0-9])))$
  • 浮点数:^(-?\d+)(.\d+)?$ 或 ^-?([1-9]\d.\d|0.\d[1-9]\d|0?.0+|0)$

二、校验字符的表达式

  • 汉字:^[\u4e00-\u9fa5]{0,}$
  • 英文和数字:^[A-Za-z0-9]+$ 或 ^[A-Za-z0-9]{4,40}$
  • 长度为3-20的所有字符:^.{3,20}$
  • 由26个英文字母组成的字符串:^[A-Za-z]+$
  • 由26个大写英文字母组成的字符串:^[A-Z]+$
  • 由26个小写英文字母组成的字符串:^[a-z]+$
  • 由数字和26个英文字母组成的字符串:^[A-Za-z0-9]+$
  • 由数字、26个英文字母或者下划线组成的字符串:^\w+$ 或 ^\w{3,20}$
  • 中文、英文、数字包括下划线:^[\u4E00-\u9FA5A-Za-z0-9_]+$
  • 中文、英文、数字但不包括下划线等符号:^[\u4E00-\u9FA5A-Za-z0-9]+$ 或 ^[\u4E00-\u9FA5A-Za-z0-9]{2,20}$
  • 可以输入含有^%&’,;=?$\”等字符:[^%&',;=?$\x22]+
  • 禁止输入含有~的字符:[^~\x22]+

三、特殊需求表达式

  • Email地址:^\w+([-+.]\w+)@\w+([-.]\w+).\w+([-.]\w+)*$

  • 域名:[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(/.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+/.?

  • InternetURL:[a-zA-z]+://[^\s] 或 ^http://([\w-]+.)+[\w-]+(/[\w-./?%&=])?$

  • 手机号码:^(13[0-9]|14[5|7]|15[0|1|2|3|5|6|7|8|9]|18[0|1|2|3|5|6|7|8|9])\d{8}$

  • 电话号码(“XXX-XXXXXXX”、”XXXX-XXXXXXXX”、”XXX-XXXXXXX”、”XXX-XXXXXXXX”、”XXXXXXX”和”XXXXXXXX):^($$\d{3,4}-)|\d{3.4}-)?\d{7,8}$

  • 国内电话号码(0511-4405222、021-87888822):\d{3}-\d{8}|\d{4}-\d{7}

  • 身份证号(15位、18位数字):^\d{15}|\d{18}$

  • 短身份证号码(数字、字母x结尾):^([0-9]){7,18}(x|X)?$ 或 ^\d{8,18}|[0-9x]{8,18}|[0-9X]{8,18}?$

  • 帐号是否合法(字母开头,允许5-16字节,允许字母数字下划线):^[a-zA-Z][a-zA-Z0-9_]{4,15}$

  • 密码(以字母开头,长度在6~18之间,只能包含字母、数字和下划线):^[a-zA-Z]\w{5,17}$

  • 强密码(必须包含大小写字母和数字的组合,不能使用特殊字符,长度在8-10之间):^(?=.\d)(?=.[a-z])(?=.*[A-Z]).{8,10}$

  • 日期格式:^\d{4}-\d{1,2}-\d{1,2}

  • 一年的12个月(01~09和1~12):^(0?[1-9]|1[0-2])$

  • 一个月的31天(01~09和1~31):^((0?[1-9])|((1|2)[0-9])|30|31)$