HOME
HOME
文章目录
  1. 0x01 基本语法
  2. 0x02 python re模块
  3. 参考

正则表达式复习

0x01 基本语法

修饰符(g i m)

  • g:global表示全局匹配
  • i:ignore case表示忽略大小写匹配
  • m:multiple line多行匹配

元字符

  • .:匹配除换行符以外的任意字符
  • \w:匹配字母、数字、下划线、汉字
  • \s:匹配任意空白字符
  • \d:匹配数字
  • \b:匹配单词的开始或者结束
  • ^:匹配字符的开始
  • $:匹配字符的结束

重复

  • *:重复0次或者多次
  • +:重复1次或者多次
  • ?:重复0次或者1次
  • {n}:重复n次
  • {n,}:重复n次到多次
  • {n,m}:重复n到m次

字符类

[]:匹配中括号中的任意一个字符

1
[abc]:匹配abc任意一个字符

反义

[^]:不包含中括号中的任意一个字符

1
[^abc]:不包含abc任意一个字符

\W:除\w意外的任意字符

\S:匹配任意不是空白符的字符

\D:匹配任意非数字的字符

\B:匹配不是单词开头或结束的位置

范围类**

[a-z]、[A-Z]、[0-9]:匹配范围内的任意一个

1
[a-zA-Z0-9]:匹配范围中的任意一个字符

贪婪与非贪婪

1
2
3
4
5
6
7
8
9
10
11
import re

s = re.search("\d{3,6}",'123456789')
print(s.group())
# output: 123456
# 贪婪模式匹配最多的情况

s = re.search("\d{3,6}?",'123456789')
# output: 123,后面加个问号,非贪婪模式,匹配最小3个的情况

a.*?b: 匹配最短的,以a开始,以b结尾的字符串

分组

abc{2}:不分组,只重复最后一个字符

1
2
3
4
5
6
7
8
>>> s = re.search("abc{2}",'abc')
>>> print(s.group())
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'NoneType' object has no attribute 'group'
>>> s = re.search("abc{2}",'abcc')
>>> print(s.group())
abcc

(abc){2}:重复abc两次

1
2
3
>>> s = re.search("(abc){2}",'abcabc')
>>> print(s.group())
abcabc

用小括号指定一个表达式后,每个分组自动拥有一个组号,从1开始编号。

\b(\w+)\b\s+\1\b:可以匹配两个空格间隔的单词,如,go go

\b(?<Word>\w+)\b\s+\k<Word>\b:可以使用组名来替代组的编号

零宽断言

用于查找某些内容,但又不占用这个位置,称为零宽断言。

(?=exp):比如\b\w+(?=ing)\b可以匹配以ing结尾的前面部分,如dancing会匹配danc

(?<=exp):比如(?<=\bre)\w+\b可以匹配re开头的单词的后半部分,如reading会匹配ading

负向零宽断言

表示某个字符或者某个字符串不在里面的方法,类似于[^abc],但这种方式只能判断单个字符,如果表示字符串不包含abc整体,则要用到负向零宽断言

(?!exp)\b((?!abc)\w)+表示不包含abc连续字符的单词

0x02 python re模块

re.compile(pattern, flags=0):编译正则表达式为一个对象,flag为标记为,可以使用|进行结合,可能的值有如下几种:

re.Are.ASCII:让\w \W \b \B \D \d s \S只匹配ASCII,忽略unicode

re.Ire.IGNORECASE:忽略匹配大小写

re.Mre.MULTILINE:匹配多行字符

常用函数

re.search(pattern, string, flag=0):扫描整个字符串,匹配到第一个就返回,并返回一个匹配对象,没有匹配返回None

1
2
3
>>> s = re.search("(abc){2}",'abcabc')
>>> print(s.group())
abcabc

re.match(pattern, string, flag=0):从字符串开头进行匹配,并返回一个匹配对象,没有匹配返回None

1
2
3
4
5
6
7
8
>>> s = re.match("abc\d+", "abc1")
>>> print(s.group())
abc1
>>> s = re.match("abc\d+", "12312abc1")
>>> print(s.group())
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'NoneType' object has no attribute 'group'

re.split(pattern, string, maxsplit=0, flags=0):用正则去分割字符串

1
2
3
>>> s = re.split('[a-f]+', 'a1b2321c912d9')
>>> print(s)
['', '1', '2321', '912', '9'] # 如果字符串第一个匹配成功,list第一位为空

re.findalll(pattern, string, flags=0):将匹配到的返回一个列表组合

1
2
3
>>> s = re.findall('abc', "abcskodqwabcjiabc")
>>> print(s)
['abc', 'abc', 'abc']

分组

如果正则中有括号进行分组,可以用group加上编号进行读取

1
2
3
4
5
6
7
>>> m = re.match(r"(\w+) (\w+)", "Isaac Newton, physicist")
>>> m.group(0)
'Isaac Newton'
>>> m.group(1)
'Isaac'
>>> m.group(2)
'Newton'

分组号有名称

1
2
3
4
5
>>> m = re.match(r"(?P<first_name>\w+) (?P<last_name>\w+)", "Malcolm Reynolds")
>>> m.group('first_name')
'Malcolm'
>>> m.group('last_name')
'Reynolds'

参考

  1. https://deerchao.cn/tutorials/regex/regex.htm
  2. https://segmentfault.com/a/1190000013075245
  3. https://segmentfault.com/a/1190000000426455
  4. 正则表达式图形化分析工具