python正则表达式必知必会

  正则是做数据分析和挖掘必须要会的一种方法,会了它很多问题其实就可以高效的解决了。说一个最常用的应用场景,在文本识别中,使用正则可以快速识别出类似于qq号、广告、联系方式等内容,很简单就可以为网站文本过滤提供支持。

1.正则表达式基础

  正则表达式有一套自己的语言系统,像人类语言一样,有几个关键字构成了它的基础语法。整理起来就是下面这几个:

  • \表示转义,一些特殊字符有特殊的意识,加\就可实现特定的意思。比如\d表示匹配数字,\s表示匹配任何不可见字符,如空格、制表符等。
  • .表示匹配任意字符,要匹配.自身,就需要转义用\.。
  • *表示匹配前面的字符0次或者多次,即即使一次不出现也无所谓。
  • +表示匹配前面的字符1次或者多次,即前面的字符至少要出现1次。
  • ?表示匹配前面的字符0次或者1次。
  • |表示或,可以匹配|前后的任意字符。
  • ^表示匹配字符串的开始位置,必须以^之后的字符开头的才能匹配。
  • $表示匹配字符串的结尾位置,必须以$之前字符结尾的才能匹配。
  • [^]当^出现在方括号里表示匹配非方括号内的任意一个字符。
  • {}表示匹配前面的字符几次,{3}表示匹配3次,{3,5}表示匹配3-5次,可以和[]一起使用。
  • <>匹配单词,如<the>可以匹配 the man中的the,却不能匹配otherwise中的the。
  • ()表示匹配一个整体,即括号里的内容必须都出现的时候才匹配,关于()还有很多衍生,实际中也比较有用。
  • (?:)非获取匹配,就是只匹配内容但却不输出,这个在re模块的fetchall中最常用,比如说industr(?:y|ies)这个能匹配industry也能匹配y但是最后只会输出industry而不输出y。
  • (?=pattern)这个也是非获取匹配,大意是先找pattern然后看之前的字符串符不符合正则,匹配完成后进行下一次的pattern匹配,也是只输出整体,而不单独输出pattern。比如Windows(?=95|98|NT|2000)能匹配Windows2000中的Windows而不能匹配Windows7中的Windows。
  • (?!pattern)这个和上面那个正好相反,在不匹配pattern的位置开始查找字符串。比如Windows(?=95|98|NT|2000)能匹配Windows7中的Windows而不能匹配Windows2000中的Windows。
  • (?<=pattern)这个东西太有意思了,和(?=pattern)是一样的,只不过方向是反的,啥意思呢,(?<=95|98|NT|2000)Windows)能匹配2000Windows里的Windows,却匹配不了7Windows里的Windows。
  • (?<!pattern),我想你已经猜到了,和(?!pattern)相同,只是方向是反的,例子我就不举了。
      会了这些,正则表达式你就入门了,剩下的看你的悟性了。

2.正则表达式常用元字符

  其实第一部分讲的也是元字符,之所以把它们拿出来说是因为太重要了,如果对正则要求不咋严格的话,第一部分就足够解决大部分问题了。下面的我就简单介绍。

  • \b,匹配单词边界,如od\b,可以匹配good,但不能匹配odd。
  • \B,匹配非单词边界,如od\B,可以匹配odd,但不能匹配good。
  • \d,匹配一个数字,等同于[0-9]。
  • \D,匹配一个非数字,等同于[^0-9]。
  • \r,匹配回车符。
  • \n,匹配换行符,经常和\r一起用。
  • \f,匹配分页符。
  • \t,匹配制表符。
  • \s,匹配任何不可见的字符,包括空格,回车符,换行符等。
  • \S,匹配任何可见字符。
  • \w,匹配包括下划线的任意字母数字字符。
    -\W,匹配非下划线、数字、字母字符。
  • \p{P},匹配任意标点符号,还有其他的用法:L字母;M:标记符号(一般不会单独出现);Z:分隔符(比如空格、换行等);S:符号(比如数学符号、货币符号等);N:数字(比如阿拉伯数字、罗马数字等);C:其他字符。这个原生的python re包是不支持的,需要安装regex包才支持,这个包有很多高阶用法,我后面介绍。
      当然还有很多表达方式,不过不经常使用,如果要用的话可以去百度。

3.python中自带的处理正则表达式的包—re

  开始之前,先说一下python对字符串的默认操作符,首先是字符串前加r,表示不转义,r"i am . frank",这个点就是代表点自身,还有一个是字符串前加u,代表采用unicode编码,对于中文的正则用的比较多。接下来说re中的函数。

  • re.compile()
      这个函数是对你写好的正则进行编译,用法就是compile(pattern, flags=0) ,它要和下面的函数搭配使用才能起作用。但是首先编译你写好的正则表达式是一种良好的编码习惯,可以使代码更整洁。
  • re.match()
      这个函数是根据写好的字符查找字符串中符合条件的部分,基本用法为re.match(pattern,str),要求必须从字符串的开头开始匹配,要提取值,可以用result.group()。这个得举例子来说了。
import re
regx1 = re.compile('\w{0,8}')
result = re.match(regx1,'itcast.cn')
#当然也可以用result = re.match('\w{0,8}','itcast.cn')
print(result)
-- 输出,注意它的输出是一个python对象,可以当逻辑判断使用
<re.Match object; span=(0, 6), match='itcast'>
  • re.search()
    跟match作用类似,所不同的是不要求必须从字符串开头开始匹配,也就是说可以匹配字符串的任意位置,返回第一个成功的匹配,基本用法为:re.search(pattern, string, flags=0)。
regx1 = re.compile('\d+')
result = re.search(regx1,'abc 123itcast.cn522abc')
print(result)
-- 输出
<re.Match object; span=(4, 7), match='123'>
  • re.findall()
      这个函数将以列表的形式返回所有匹配到的字符,因为返回的是字符列表所以比match函数要常用,基本用法为findall(pattern, string, flags=0),参数的含义和match一样,还是来看案例。
regx2 = re.compile('[t,w]h')
result = re.findall(regx2,'https://docs.python.org/3/whatsnew/3.6.html')
print(result)
--输出
['th', 'wh']

  这个函数有个坑我必须要说一下,就是如果有括号的话,那么括号里的内容都会匹配一遍。

regx3 = re.compile(r'(.*([w]h).*)')
result = re.findall(regx3,'https://docs.python.org/3/whatsnew/3.6.html')
print(result)
--输出
[('https://docs.python.org/3/whatsnew/3.6.html', 'wh')]

  咋办呢,用第一部分的?:解决。

regx4 = re.compile(r'(.*(?:[w]h).*)')
result = re.findall(regx4,'https://docs.python.org/3/whatsnew/3.6.html')
print(result)
--输出
['https://docs.python.org/3/whatsnew/3.6.html']
  • re.split()
      这个函数的作用是以写好的正则表达式为分割符,对字符串进行分割后以列表形式返回分割之后的结果。
regx4 = re.compile(r'\d+')
print(regx4.split('one1two2three3four4'))
-- 输出
['one', 'two', 'three', 'four', '']
  • re.sub()
      这是第一版介绍的最后一个函数,这个函数的作用是替换,返回的是匹配之后的结果。基本用法为re.sub(pattern, repl, string, count=0, flags=0)
    ,其中pattern,repl,string是必选参数,repl的意思是用什么字符串去替换正则匹配到的字符串。
regx5 =re.compile( "\d+")
result = re.sub(regx5, '_add111', 'hello 123 world 456 nihao 789',2)
print(result)
--输出
hello _add111 world _add111 nihao 789

  还有一些高阶函数,如果我用上了,我会继续补充的,目前笔者工作中还是没有遇到的。

4.3.python正则表达式进阶—regex

  这个包不是python自带的,需要pip install安装,安装很简单。它提供了很多附加的正则表达式功能。

  • 支持unicode代码属性,如u'[\u4e00-\u9fa5]'表示任意中文字符,\p{Cyrillic}表示西里尔字符,更多用法可以使用过程中百度。
  • 支持模糊匹配,有三种模式:i,模糊插入、d,模糊删除、s,模糊替换。
import regex
regex.findall('(?:hello){s<=2}', 'hallo')
--输出
['hallo']
  • 支持可以复用的程序子句,用(?(DEFINE)...)进行操作
regex.search(r'(?(DEFINE)(?P<quant>\d+)(?P<item>\w+))(?&quant) (?&item)', '5 elephants')
-- 输出
<regex.Match object; span=(0, 11), match='5 elephants'>

  此后可以用(?&quant)表示\d+,(?&item)表示\w+,特别适用于子句复杂的情况。
  更多功能待探索后补充。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 162,547评论 4 374
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 68,787评论 2 308
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 112,175评论 0 254
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,752评论 0 223
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 53,169评论 3 297
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 41,056评论 1 226
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 32,195评论 2 321
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,980评论 0 214
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,724评论 1 250
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,872评论 2 254
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,344评论 1 265
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,667评论 3 264
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,379评论 3 245
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,202评论 0 9
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,992评论 0 201
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 36,189评论 2 286
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,987评论 2 279

推荐阅读更多精彩内容

  • Python中的正则表达式(re) import rere.match #从开始位置开始匹配,如果开头没有则无re...
    BigJeffWang阅读 6,942评论 0 99
  • 搞懂Python 正则表达式用法 Python 正则表达式 正则表达式是一个特殊的字符序列,它能帮助你方便的检查一...
    厦热阅读 1,543评论 0 2
  • re模块手册 本模块提供了和Perl里的正则表达式类似的功能,不关是正则表达式本身还是被搜索的字符串,都可以...
    喜欢吃栗子阅读 3,909评论 0 13
  • #首先,python中的正则表达式大致分为以下几部分: 元字符 模式 函数 re 内置对象用法 分组用法 环视用法...
    mapuboy阅读 1,547评论 0 51
  • 这段日子,我发现老公吃饭总是玩手机,低着头眼睛盯着屏幕,偶尔抬头夹点菜扒口饭。 于是我说,就不能好好吃饭了吗?他答...
    擦擦阅读 442评论 1 2