python--正则表达式

什么是正则表达式

基本说来,正则表达式是一种用来描述一定数量文本的模式。Regex代表Regular Express。我们使用一种自定义的模式来匹配一定数量的文本,并从中提取所需数据。如同window的通配符,如:.txt查找所有txt文件。就被解释成任意字符。

python中的正则表达式大致分为以下几部分:

  • 元字符
  • 模式
  • re 内置对象用法

所有关于正则表达式的操作都使用 python 标准库中的 re 模块。

Python中的re模块

import re  # 导入re模块
dir(re)  # 查看re模块的方法和属性
['A', 'ASCII', 'DEBUG', 'DOTALL', 'I', 'IGNORECASE', 'L', 'LOCALE', 'M', 'MULTILINE', 'RegexFlag', '
S', 'Scanner', 'T', 'TEMPLATE', 'U', 'UNICODE', 'VERBOSE', 'X', '_MAXCACHE', '__all__', '__builtins_
_', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', '__ver
sion__', '_alphanum_bytes', '_alphanum_str', '_cache', '_compile', '_compile_repl', '_expand', '_loc
ale', '_pattern_type', '_pickle', '_subx', 'compile', 'copyreg', 'enum', 'error', 'escape', 'findall
', 'finditer', 'fullmatch', 'functools', 'match', 'purge', 'search', 'split', 'sre_compile', 'sre_pa
rse', 'sub', 'subn', 'template']

一、常见的元字符及用法

元字符 表述 表达式示例 完整匹配的字符串
. 匹配任意字符(不包括换行符\n) a.c abc
\ 转义字符,使跟在其后的字符将失去作为特殊元字符的含义例如\.只能匹配.,不能再匹配任意字符 a.c a.c
[...] 字符集,一个字符的集合,可匹配其中任意一个字符 a[bcd]e abe/ace/ade
预定义字符(可以写在字符集[...])
\d 匹配一个数字 [0-9] a\dc a1c
\D 匹配非数字 [^0-9]|[^\d] a\Dz ajz/a z/a*z/...
\s 匹配任意空白字符 [<空格> \t\n\r\f\v] a\sc a c/a\t/a\n/...
\S 匹配非空白字符[^ \t\n\r\f\v]]|[^\s] a\Sc axc/a>c/a水c/...
\w 匹配数字、字母、下划线中任意一个字符[a-zA-Z0-9_] a\wc aac/aZc/a3c/a_c
\W 匹配非数字、字母、下划线中的任意字符 [^a-zA-Z0-9_] a\Wc a c/a得c/a+c/...
数量词(用在字符或(...)之后)
* 匹配前一个元字符0到多次 abc* ab/abcccc
+ 匹配前一个元字符1到多次 abc+ abc/abccc
? 匹配前一个元字符0到1次 goo? goo/go
{m} 匹配前一个元字符m次 a{3} aaa
{m,n} 匹配前一个元字符m到n次 [0-9]{2,5} 11/1111/11111
*?/+?/??/{m,n}? 使*?/+?/??/{m,n}?变成非贪婪模式 示例参照下文
边界匹配(不消耗待匹配字符串中的字符)
^ 匹配开始位置,多行模式下匹配每一行的开始 ^Dear Dear
[^x] 匹配除了x以外的任意字符 [^abcd] a
$ 匹配结束位置,多行模式下匹配每一行的结束 .*sh$ wddefsh
\b 匹配一个单词边界,匹配\w和\W之间的单词也就是指单词和空格间的位置。例如,“er\b”可以匹配“never”中的“er”,但不能匹配“verb”中的“er”(与\B相反) a\b!ac a!ac
\B 匹配非单词边界 [^\b] “er\B”能匹配“verb”中的“er”,但不能匹配“never”中的“er” a\Bss ass
\A 匹配字符串开始位置,忽略多行模式 \ADear Dear
\Z 匹配字符串结束位置,忽略多行模式 .*ar\Z ar/sffar
逻辑分组
| 代表左右表达式任意匹配 “或” 他总是先匹配 |左边的表达式,一旦满足条件则直接跳过右边的条件 如果|没有在()则他的范围是整个表达式 abc|def abc/def
(...) 分组,默认为捕获,即被分组的内容可以被单独取出,默认每个分组有个索引,从 1 开始,按照"("的顺序决定索引值 ([0-9]{3})f(oo l u)bar 234foobar/012fubar
(?P<name>...) 分组的命名模式,取此分组中的内容时可以使用索引也可以使用name (?P<id>abd){2} abdabd
\<number> 引用<name>的分组匹配到的字符串 (\d)abd\1 1abd1/4abd4
(?P=name) 分组的引用模式,可在同一个正则表达式用引用前面命名过的正则 (?P<id>\d)abc(?P=id) 1abc1/4abc4
特殊构造(不作为分组)
(?iLmsux) 分组中可以设置模式,iLmsux之中的每个字符代表一个模式,只能用在正则表达式的开头用法参见 模式 1 (?abc) AbC
(?:...) 分组的不捕获模式,计算索引时会跳过这个分组 (?:abc){2} abcabc
(?#...) 注释,不影响正则表达式其它部分 abc(?#coment)123 abc123
(?=...) 之后的字符串内容需要匹配表达式才能成功匹配。不消耗字符串内容 a(?=\d) a后面是数字
(?!...) 之后的字符串内容需要不匹配表达式才能成功匹配。不消耗字符串内容。 a(?!\d) a后面不能是数字
(?<=...) 之前的字符创内容需要匹配表达式才能成功匹配。不消耗字符串内容 (?<=\d)a 前面是数字的a
(?<!...) 之前的字符创内容需要不匹配表达式才能成功匹配。不消耗字符串内容 (?!=\d)a 前面不是数字的a
(?(id/name)yes no) 若前面指定id或name的分区匹配成功则执行yes处的正则,否则执行no处的正则 (\d)abc(?1)\d|abc) 1abc2/abcabc
\number 匹配和前面索引为number的分组捕获到的内容一样的字符串

重复与贪婪重复和惰性重复

重复的含义是指重复匹配满足某一匹配模式的文本。
如例中(匹配ip)的’?’号就是一个重复的例子,它的含义是某一匹配模式,至多出现一次。以下列出一些重复的标示:

  1. * :星号,重复任意多次,如:\w*,代表任意字母,数字,下划线,汉字出现任意多次
  2. + :加号:至少出现一次,如:\d+,代表任意数字至少出现一次
  3. ? :问好:至多出现一次(出现一次或则不出现),如:\s?,代表空白字符出现0或则1次
  4. {n}:n代表任意数字,如:.{5},代表任意字符出现5次
  5. {n,}:n代表任意数字,如:\d{5,},代表任意数字出现5到多次
  6. {n,m}:n,m代表任意数字,如:\d{5,10},代表任意数字出现5到10次
1)re.match("[A-Z][a-z]*","Liujianhong ")

  re.match("[A-Za-z]*","LiuJianhong ")

  re.match("[A-Z][a-z]*","LiuJianhong ")

2)re.match("[a-zA-Z_]+[\w_]*","LiuJianhong3 ")

3)re.match("[0-9]?[\d]","1")

  re.match("[0-9]?[\d]","111")

4)re.match("\w{5}","1sadfasdf11")

5)re.match("\w{5,}","1sadfasdf11")

6)re.match("\w{5,9}","1sadfasdf11")

re.match(".*\\bliu\\b","i is liu fas fsa5 662 2a") # 注意为什么使用点

re.match(r".*\bliu\b","i is liu fas fsa5 662 2a")  #结果同上

贪婪与惰性匹配

首先看一个正则表达式例子:“<.>”
这个正则表达式将匹配以’<’开头,’>’结尾中间任意次任意字符,
如:<br/>,<div/>,</script>等。
当如果用该正则表达式去匹配<div>hello world</div>的话被匹配出的文本就是<div>hello world</div>,因为默认情况下正则表达式是贪婪匹配。正则表达式引擎或默认情况下将默认搜索最后一个匹配锚点。所以本例中的最后匹配锚点是</div>的>而不是<div>的>。这便是贪婪匹配。
既然明白有贪婪匹配,就必然需知惰性匹配
以上为上面这个正则表达式例子稍作改动:<.
?>,我们在*后面加上一个问号便告诉引擎按照惰性匹配的方式进行搜索,使用这个正则表达式匹配<div>hello world</div>得到的结果会有两个,一个是<div>另一个是</div>。因为我们没有限定开头和结尾。

字符集

字符集:[A-Za-z0-9],匹配一个字符,这个字符是A-Za-z0-9中的任意一个

分歧

分歧:(a|b)*,a或则b出现任意多次

反义:

代码/语法 说明
\W <u>匹配任意不是字母,数字,下划线,汉字的字符</u>
\S <u>匹配任意不是空白符的字符</u>
\D <u>匹配任意非数字的字符</u>
\B <u>匹配不是单词开头或结束的位置</u>
[^x] <u>匹配除了x以外的任意字符</u>
[^aeiou] <u>匹配除了aeiou这几个字母以外的任意字符</u>
[^ab]+ 非a和b出现至少一次

分组

正则表达式的分组以()小括号进行标示,

re.match("100|[1-9][0-9]|[0-9]","2") # 匹配100以内的数

re.match("100|[1-9]?\d$","2") 

re.match("\d+(183|192|168)\s","452183 ")

re.match("\d+(183|192|168)\s","452183 ").group()

re.match("\d+(183|192|168)\s","452183 ").group(1) #注意当输入1的结果

re.match("\d+(183|192|168)\.(li|wang|liu)","452168.wang").group(2) 

re.match("(.*)-(\d+)","0931-5912872 ").group(2) #小括号的使用场景,特别方便

re.match("<[a-zA-Z]*>\w*</[a-zA-Z]*>","<a>liujianhong</a>") #看似正确,其实Error

re.match("<[a-zA-Z]*>\w*</[a-zA-Z]*>","<a>liujianhong</html>") #这个就是漏洞

re.match(r"<([a-zA-Z] *)>\w*</ \1>","<a>liujianhong</html>") #此时\1表示第一个括号中的值

re.match("<([a-zA-Z] *)>\w*</ \\1>","<a>liujianhong</html>") #这样也行

常用正则表达式

功能 语法 表述
用户名 /^[a-z0-9_-]{3,16}$/ 只能包含小写字母、数字、_、-(至少3位,最多16位)
密码 /^[a-z0-9_-]{6,18}$/ 只能包含小写字母、数字、-、_(至少3位,最多18位)
十六进制值 /^#?([a-f0-9]{6}|[a-f0-9]{3})$/ 以“#”开头(也可无)6位或3位
电子邮箱 /^([a-z0-9_.-]+)@([\da-z.-]+).([a-z.]{2,6})$/
/^[a-z\d]+(.[a-z\d]+)*@(\da-z?)+(.{1,2}[a-z]+)+$/
URL /^(https?://)?([\da-z.-]+).([a-z.]{2,6})([/\w .-])/?$/
IP 地址 r"/((2[0-4]\d|25[0-5]|[01]?\d\d?).){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)//^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/
HTML 标签 /<([a-z]+)([<]+)(?:>(.)</\1>|\s+/>)$/
删除代码\注释 (?<!http:|\S)//.*$
Unicode编码中的汉字范围 /^[\u2E80-\u9FFF]+$/
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,937评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,503评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,712评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,668评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,677评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,601评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,975评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,637评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,881评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,621评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,710评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,387评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,971评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,947评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,189评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,805评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,449评论 2 342

推荐阅读更多精彩内容

  • re模块手册 本模块提供了和Perl里的正则表达式类似的功能,不关是正则表达式本身还是被搜索的字符串,都可以...
    喜欢吃栗子阅读 3,977评论 0 13
  • #首先,python中的正则表达式大致分为以下几部分: 元字符 模式 函数 re 内置对象用法 分组用法 环视用法...
    mapuboy阅读 1,597评论 0 51
  • 前言: 什么是正则表达式? 正则表达式(Regular expressions 也称为 REs,或 regexes...
    小喜_ww阅读 3,677评论 3 7
  • 正则表达式 1. 正则表达式概述 正则表达式,又称正规表示式、正规表示法、正规表达式、规则表达式、常规表示法(英语...
    PythonMaO阅读 1,261评论 0 1
  • 不知道睡过多少个地方:集体宿舍,火车上,大巴,船上。通铺,天地床。过去的岁月,从这里搬挪到那里,从一个少年变成了大...
    昇夫阅读 462评论 0 2