Python数据分析与挖掘之正则表达式详解

什么是正则表达式

世界上信息非常多,而我们关注的信息有限。假如我们希望只提取出关
注的数据,此时可以通过一些表达式进行提取,正则表达式就是其中一
种进行数据筛选的表达式。

原子

原子是正则表达式中最基本的组成单位,每个正则表达式中至少要包含
一个原子。常见的原子类型有:

  • a普通字符作为原子
  • b非打印字符作为原子
  • c通用字符作为原子
  • d原子表

正则表达式函数

正则表达式函数有re.match()函数、re.search()函数、全局匹配函数、 re.sub()函数。

re.search

re.search 扫描整个字符串并返回第一个成功的匹配。

import re

pat = "yue"
string = "http://iqianyue.com"
result = re.search(pat,string)
print(result)

输出结果如下:

<_sre.SRE_Match object; span=(12, 15), match='yue'>

re.match

re.match 尝试从字符串的起始位置匹配一个模式,如果不是起始位置匹配成功的话,match()就返回none。

import re

pat = "yue"
string = "yuehttp://iqyueianyue.com"
result = re.match(pat,string)
print(result)

输出结果如下:

<_sre.SRE_Match object; span=(0, 3), match='yue'>

全局匹配函数 re.compile().findall():

扫描整个字符串并以列表的形式返回符合条件的匹配值

import re 

pat = "p.*?n"
string = "abcpythonjgkhappynn"
result = re.compile(pat).findall(string)
print(result)

输出结果如下:

['python', 'ppyn']

re.match与re.search的区别

re.match只匹配字符串的开始,如果字符串开始不符合正则表达式,则匹配失败,函数返回None;而re.search匹配整个字符串,直到找到一个匹配。

模式修正符

所谓模式修正符,即可以在不改变正则表达式的情况下,通过模式修正符改变正则表达式的含义,从而实现一些匹配结果的调整等功能。
正则表达式中常用的模式修正符有i、g、m、s、x、e等。它们之间可以组合搭配使用。

  • 修正符:i不区分大小写的匹配;
  • 修正符:m将字符串视为多行,不管是那行都能匹配;
  • 修正符:s将字符串视为单行,换行符作为普通字符;
  • 修正符:x将模式中的空白忽略;
  • 修正符:A强制从目标字符串开头匹配;
  • 修正符:D如果使用$限制结尾字符,则不允许结尾有换行;
  • 修正符:U只匹配最近的一个字符串;不重复匹配;

举例如下:

import re

pat = "bai"
string = "http://www.Baidu.com"
result = re.search(pat,string,re.I)#不区分大小写
print(result)

贪婪模式与懒惰模式

贪婪模式的核心点就是尽可能多的匹配,而懒惰模式的核心点就是尽可能少的匹配(更精确的定位)。

import re

pat1 = "p.*y"#贪婪模式(尽可能多的匹配)
pat2 = "p.*?y"#懒惰模式(尽可能少的匹配)
string = "abcpythonfghappy"
result1 = re.search(pat1,string)
result2 = re.search(pat2,string)
print(result1)
print(result2)

输出结果如下:

<_sre.SRE_Match object; span=(3, 16), match='pythonfghappy'>
<_sre.SRE_Match object; span=(3, 5), match='py'>

正则表达式实例

实例 描述
python 匹配 "python"
[Pp]ython 匹配 "Python" 或 "python"
rub[ye] 匹配 "ruby" 或 "rube"
[aeiou] 匹配中括号内的任意一个字母
[0-9] 匹配任何数字。类似于 [0123456789]
[a-z] 匹配任何小写字母
[A-Z] 匹配任何大写字母
[a-zA-Z0-9] 匹配任何字母及数字
[^aeiou] 除了aeiou字母以外的所有字符
. 匹配除 "\n" 之外的任何单个字符。要匹配包括 '\n' 在内的任何字符,请使用象 '[.\n]' 的模式。
\d 匹配一个数字字符。等价于 [0-9]。
\D 匹配一个非数字字符。等价于 [^0-9]。
\s 匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]。
\S 匹配任何非空白字符。等价于 [^ \f\n\r\t\v]。
\w 匹配包括下划线的任何单词字符。等价于'[A-Za-z0-9_]'。
\W 匹配任何非单词字符。等价于 '[^A-Za-z0-9_]'。

非打印字符

元字符 描述
\cx 匹配由x指明的控制字符。例如, \cM 匹配一个 Control-M 或回车符。x 的值必须为 A-Z 或 a-z 之一。否则,将 c 视为一个原义的 'c' 字符。
\f 匹配一个换页符。等价于 \x0c 和 \cL。
\n 匹配一个换行符。等价于 \x0a 和 \cJ。
\r 匹配一个回车符。等价于 \x0d 和 \cM。
\s 匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]。
\S 匹配任何非空白字符。等价于 [^ \f\n\r\t\v]。
\t 匹配一个制表符。等价于 \x09 和 \cI。
\v 匹配一个垂直制表符。等价于 \x0b 和 \cK。

特殊字符

特别字符 描述
$ 匹配输入字符串的结尾位置。如果设置了 RegExp 对象的 Multiline 属性,则 $ 也匹配 '\n' 或 '\r'。要匹配 $ 字符本身,请使用 $。
( ) 标记一个子表达式的开始和结束位置。子表达式可以获取供以后使用。要匹配这些字符,请使用 \( 和 \)。
* 匹配前面的子表达式零次或多次。要匹配 * 字符,请使用 \*。
+ 匹配前面的子表达式一次或多次。要匹配 + 字符,请使用 \+。
. 匹配除换行符 \n 之外的任何单字符。要匹配 . ,请使用 \. 。
[ 标记一个中括号表达式的开始。要匹配 [,请使用 \[。
? 匹配前面的子表达式零次或一次,或指明一个非贪婪限定符。要匹配 ? 字符,请使用 \?。
\ 将下一个字符标记为或特殊字符、或原义字符、或向后引用、或八进制转义符。例如, 'n' 匹配字符 'n'。'\n' 匹配换行符。序列 '\' 匹配 "",而 '(' 则匹配 "("。
^ 匹配输入字符串的开始位置,除非在方括号表达式中使用,此时它表示不接受该字符集合。要匹配 ^ 字符本身,请使用 \^。
{ 标记限定符表达式的开始。要匹配 {,请使用 \{。
指明两项之间的一个选择。

限定符

字符 描述
* 匹配前面的子表达式零次或多次。例如,zo* 能匹配 "z" 以及 "zoo"。* 等价于{0,}。
+ 匹配前面的子表达式一次或多次。例如,'zo+' 能匹配 "zo" 以及 "zoo",但不能匹配 "z"。+ 等价于 {1,}。
? 匹配前面的子表达式零次或一次。例如,"do(es)?" 可以匹配 "do" 、 "does" 中的 "does" 、 "doxy" 中的 "do" 。? 等价于 {0,1}。
{n} n 是一个非负整数。匹配确定的 n 次。例如,'o{2}' 不能匹配 "Bob" 中的 'o',但是能匹配 "food" 中的两个 o。
{n,} n 是一个非负整数。至少匹配n 次。例如,'o{2,}' 不能匹配 "Bob" 中的 'o',但能匹配 "foooood" 中的所有 o。'o{1,}' 等价于 'o+'。'o{0,}' 则等价于 'o*'。
{n,m} m 和 n 均为非负整数,其中n <= m。最少匹配 n 次且最多匹配 m 次。例如,"o{1,3}" 将匹配 "fooooood" 中的前三个 o。'o{0,1}' 等价于 'o?'。请注意在逗号和两个数之间不能有空格。

python中正则表达式常用场景

  • 匹配.com或.cn网址
import re 

pat = "[a-zA-Z]+://[^\s]+[.com|.cn]"
string = '<a href="http://www.baidu.com></a>">'
result = re.compile(pat).findall(string)
print(result)

输出如下:

['http://www.baidu.com']
  • 匹配JavaScript带标签的网址

比如从 https://read.douban.com/provider/all中将所有出版社提取出来,把无关信息过滤掉。<div class="name">北京师范大学出版社</div>

import urllib
import re

# <div class="name">北京师范大学出版社</div>
url = "https://read.douban.com/provider/all"
pat = '<div class="name">(.*?)</div>'
data = urllib.request.urlopen(url).read().decode("utf-8","ignore")
result = re.compile(pat).findall(data)
print(result)

输出结果如下:

['博集天卷', '北京邮电大学出版社', '北京师范大学出版社', '百花洲文艺出版社', '百花文艺出版社', '长江数字', '重庆大学出版社', '东方文萃', '读客图书', '电子工业出版社', '当代中国出版社', '第一财经周刊', '豆瓣阅读同文馆', '豆瓣', '豆瓣阅读', '豆瓣阅读出版计划', '东方巴别塔文化', '凤凰壹力', '凤凰悦世泓文', '凤凰联动', 'Fiberead', '复旦大学出版社', '凤凰雪漫', '果壳阅读', '果麦文化', '广西师范大学出版社', '杭州蓝狮子文化创意股份有限公司', '后浪出版公司', '华东师范大学出版社', '华章数媒', '汉唐阳光', '华文时代', '湖北人民出版社', '华章同人', '华夏盛轩', '海豚出版社', '虹膜出版', '化学工业出版社', '华中科技大学出版社', '湖北科学技术出版社', '黑龙江北方文艺出版社', '华文经典', 'HarperCollins', '聚石文华', '金城出版社', '简书', '今古传奇', '江苏人民出版社', '九州幻想', '科幻世界', '酷威文化', '理想国', '漓江出版社', '磨铁数盟', '宁波出版社', '南方人物周刊', 'ONE·一个', '浦睿文化', 'Parkstone International', 'Packt Publishing', '清华大学出版社', '青岛出版社', '《人物》杂志', '人民文学出版社', '人民邮电出版社', '儒意欣欣', '人民东方出版传媒', '人民文学杂志社', '上海九久读书人', '世纪文景', '四川数字出版传媒有限公司', '上海译文出版社', '时代华文', '上海雅众文化', '世纪文睿', '时代华语', '商务印书馆', '生活·读书·新知三联书店', '上海社会科学院出版社', '社会科学文献出版社', '山西春秋电子音像出版社', '时代数联', '陕西人民出版北京分公司', '《书城》杂志', '世图北京', '四川文艺出版社', '上海文艺出版社', '上海人民出版社', '上海交通大学出版社', '斯坦威图书', '上海人民美术出版社', '图灵社区', 'Trajectory', '武汉大学出版社北京分社', '万有图书', '我和豆瓣', '新经典文化电子书', '新星出版社', '新华先锋文化传媒', '雪球', '悬疑世界', '现代出版社', '西南财经大学出版社', '新华出版社', '新华先锋出版科技', '译林出版社', '译言·东西文库', '译言·古登堡计划', '悦读纪', '阳光博客', '悦读名品', '燕山出版社', '阅文集团华文天下', '中信出版社', '中国人民大学出版社', '中作华文', '中国轻工业出版社', '紫图图书', '浙版数媒', '中央编译出版社', '知乎', '中国国家地理图书部', '浙江摄影出版社', '中国经济出版社', '中国青年出版社', '中国民主法制出版社', '中国传媒大学出版社', '中国言实出版社', '浙江大学出版社', '湛庐文化', '浙江文艺出版社', '中华书局']
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,884评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,347评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,435评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,509评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,611评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,837评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,987评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,730评论 0 267
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,194评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,525评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,664评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,334评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,944评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,764评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,997评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,389评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,554评论 2 349

推荐阅读更多精彩内容