Python正则表达式
上次攻防赛在写自动提交flag脚本的时候,因为不会正则,在处理非标准flag格式的时候很捉急,赛后学了一下,并不是很难
Python正则表达式
创建正则表达式对象
首先引入模块
import re
向re.compile()
传入一个字符串值,表示正则表达式,它将返回一个 Regex对象
如:
numRegex=re.compile(r'\d\d\d')
\d
表示0-9的数字,此时这个表达式匹配的就是连续的三个数字
过在字符串的第一个引号之 前加上 r,可以将该字符串标记为原始字符串
匹配Regex对象
Regex 对象的search()
方法将会查找传入的字符串,寻找该正则表达式的所有匹配。
如匹配字符串asd123fdsxxx
中的连续的三个字母
1 | >>> import re |
会发现返回了第一个匹配到的连续三个数字123
如果想要找到所有匹配的地方,可以使用findall()
方法
1 | >>> import re |
此时会把所有匹配到的结果以一个list的形式返回出来
使用括号分组
有这样一串字符串china +86-1777
可以看成是电话号,前面的+86是国际区号
如果想将区号从电话号中分离,可以使用括号在正则表达式中创建分组
1 | >>> numRegex=re.compile(r'\+(\d\d)-(\d\d\d\d)') |
用管道匹配多个分组
如字符串apple and pair
如果想匹配apple
或者pair
可使用正则表达式 r'apple|pair'
如果两个内容都出现在被查找的字符串中,第一次出现的匹配文本, 将作为 Match 对象返回
1 | >>> regex=re.compile(r'apple|pair') |
用?实现可选匹配
可选匹配的意思是不论这段文本在不在,正则表达式都会认为匹配
比如想匹配 hackernews
或者hackersnews
表达式的内容则为r'hacker(s)?news'
?可以理解为,“匹配这个问号之前的分组零次或一次”
1 | >>> regex=re.compile(r'hacker(s)?news') |
多次匹配
*
:匹配零次或多次+
:匹配一次或多次{x}
:匹配特定x次{a,b}
:匹配[a,b]次,可以不限制最大值或者不限制最小值
1 | >>> str1='test sr' |
贪心匹配
Python 的正则表达式默认是“贪心”的,这表示在有二义的情况下,它们会尽可能匹配最长的字符串
比如 使用表达式r'(ha){3,5}'
去匹配’hahahahaha’
默认会匹配最长的字符串’hahahahaha’
如果要使用非贪心模式,则要在花括号后面加一个?
如r'(ha){3,5}?
此时会匹配最短的字符串’hahaha’
上面提到的其他多次匹配的方式同理
如r'(ha)+?'
,r'(ha)*?'
问号在正则表达式中可能有两种含义:声明非贪心匹配或表示可选的分组。这两种含义是完全无关的。
findall()方法
search()
将返回一个Match 对象,包含被查找字符串中的“第一次”匹配的文本,而findall()
方法将返回一组字符串,包含被查找字符串中的所有匹配。
如上面提到的:
如果想要找到所有匹配的地方,可以使用findall()
方法
1 | >>> import re |
常用字符
分类 | 含义 |
---|---|
\d | 0-9的数字 |
\D | 0-9以外的任意字符 |
\w | 任何字母,数字或下划线 |
\W | 除字母,数字,和下划线以外的字符 |
\s | 空格,制表符或换行符 |
\S | 除空格,制表符和换行符以外的字符 |
. | 通配符,匹配除了换行之外的所有 字符 |
创建字符分类
可以使用方括号定义自己的字符分类
如[aeiouAEIOU]
将匹配所有的元音字母
1 | >>> vowelRegex = re.compile(r'[aeiouAEIOU]') |
在字符分类的左方括号后加上一个插入字符(^),就可以得到“非字符类”。
将匹配不在这个字符类中的所有字符
1 | >>> consonantRegex = re.compile(r'[^aeiouAEIOU]') |
完整匹配
在正则表达式的开始处使用插入符号(^),表明匹配必须发生在被查找文 本开始处。
可以再正则表达式的末尾加上美元符号($),表示该字符串必 须以这个正则表达式的模式结束。
可以同时使用^和$,表明整个字符串必须匹配该 模式,也就是说,只匹配该字符串的某个子集是不够的。 此时正则表达式将匹配整个字符串
如正则表达式 r’^\d+$’匹配从开始到结束都是数字的字符串
1 | >>> wholeStringIsNum = re.compile(r'^\d+$') |
如果使用了^和$,那么整个字符串必须匹配该正则表达式。
不区分大小写
默认的正则表达式会匹配大小写,如果想不匹配大小写,可以向re.compile()
传入re.I
作为第二个参数
如:
>>> robocop = re.compile(r'rob', re.I)
速记
- ?匹配零次或一次前面的分组。
- *匹配零次或多次前面的分组。
- +匹配一次或多次前面的分组。
- {n}匹配 n 次前面的分组。
- {n,}匹配 n 次或更多前面的分组。
- {,m}匹配零次到 m 次前面的分组。
- {n,m}匹配至少 n 次、至多 m 次前面的分组。
- {n,m}?或*?或+?对前面的分组进行非贪心匹配。
- ^spam 意味着字符串必须以 spam 开始。
- spam$意味着字符串必须以 spam 结束。
- .匹配所有字符,换行符除外。
- \d、\w 和\s 分别匹配数字、单词和空格。
- \D、\W 和\S 分别匹配出数字、单词和空格外的所有字符。
- [abc]匹配方括号内的任意字符(诸如 a、b 或 c)。
- [^abc]匹配不在方括号内的任意字符。