字符串的表现形式
- '\n' 代表一个字符 n,只是这个 n 的意思(换行)与平时(字母 n)不一样,故称为「转义字符」,反斜杠标识该字符与众不同而已
- r'\n' 代表两个字符,一个是反斜杠,一个是字母 n
正则原理
rex = r'a.d' # 正则文本
original_str = 'and' # 原始文本
pattern = re.compile(rex) #正则文本编译成正则对象
print(type(pattern)) # <class '_sre.SRE_Pattern'>
print(pattern.match(original_str))# <_sre.SRE_Match object; span=(0, 3), match='and'>
等价于:
print(re.match(r'a.d', 'and')) # <_sre.SRE_Match object; span=(0, 3), match='and'>
Pattern 对象匹配原始文本,成功匹配则返回 Match 对象,匹配失败返回 None
元字符
正则表达式由「普通字符」和「元字符」组成
基本元字符和预设元字符都只是匹配一个字符
-
基本元字符
-
.
:匹配除换行符以外的任意一个字符 - \: 转义字符,使元字符具有本来的意义
- [...]:匹配方括号中的任意一个字符, “[]” 中的元字符失效,变为普通字符
- [^ ...]:字符集取反,表示只要不是括号中出现的字符都可以匹配
print(re.match(r'a.d', 'a\nd')) # None,点不能匹配换行符
print(re.match(r'a.d', 'a\bd')) # 匹配成功!
print(re.match(r'a\.d', 'a.d')) # 点此处是普通字符
print(re.match(r'a[.*?]d', 'and')) # None 点在此处是普通字符
print(re.match(r'a[a-z]d', 'and')) # 中括号内加 - ,表示范围
print(re.match(r'a[^0-9]d', 'and')) # 中括号内第一个字符是 ^ ,表示非
-
预设元字符
\s:匹配一个空白字符,空格、换行等,与 \S 相反
\d:匹配一个数字,即:[0-9],与 \D 相反
\w:匹配一个字母、数字、下划线,即:[A-Za-z0-9_],与 \W 相反
-
边界匹配
^:匹配字符开头
$:匹配字符结尾
-
重复匹配
* 重复匹配 x 次,即零次或以上
? 重复匹配零次或者一次
+ 重复匹配一次或者多次
{n} 重复匹配n次
{n,} 重复匹配至少n次
{n, m} 重复匹配n到m次
-
逻辑分支
逻辑分支条件字符 |,它把表达式分为左右两部分,先尝试匹配左边部分,如果匹配成功就不再匹配右边部分了
re.match(r"\d{3}-\d{8}|\d{4}-\d{7}", "010-34827637") # 匹配成功
-
分组
# 圆括号括起来表示分组
print(re.match(r"(\d+)(\w+)", "1234abcd").group()) # 1234abcd
print(re.match(r"(\d+)(\w+)", "1234abcd").group(0)) # 同上
print(re.match(r"(\d+)(\w+)", "1234abcd").group(1)) # 1234
print(re.match(r"(\d+)(\w+)", "1234abcd").group(2)) # abcd
# 指定组名:(?P<name>正则)
print(re.match(r"(?P<digital>\d+)(?P<char>\w+)", "1234abcd").group('digital')) # 1234
-
贪婪与非贪婪匹配
print(re.match(r"a.*b", "aaabcb").group()) # aaabcb 默认贪婪匹配
print(re.match(r"a.*?b", "aaabcb").group()) # aaab 非贪婪匹配:量词后面加问号