Skip to content

正则-表达式

  • 正则表达式是一种用于匹配和操作文本的强大工具,它是由一系列字符和特殊字符组成的模式,用于描述要匹配的文本模式。
  • 正则表达式可以在文本中查找、替换、提取和验证特定的模式。

元字符

基本

  • .: 匹配任意字符(除了换行符)。
  • ^: 匹配字符串的开头。
  • $: 匹配字符串的结尾。
  • [a-z]:匹配任意小写字母。
  • [A-Z]:匹配任意大写字母。
  • [0-9]:匹配任意数字字符。
  • [a-zA-Z0-9_]:匹配任意字母、数字或下划线字符。

量词

  • *:匹配前面的模式零次或多次。
  • +:匹配前面的模式一次或多次。
  • ?:匹配前面的模式零次或一次。
  • {n}:匹配前面的模式恰好 n 次。
  • {n,}:匹配前面的模式至少 n 次。
  • {n,m}:匹配前面的模式至少 n 次且不超过 m 次。

字符类

  • []:匹配括号内的任意一个字符。例如,[abc] 匹配字符 "a"、"b" 或 "c"。
  • [^]:匹配除了括号内的字符以外的任意一个字符。例如,[^abc] 匹配除了字符 "a"、"b" 或 "c" 以外的任意字符。
  • -:匹配连字符,用于表示字符范围。例如,[a-z] 匹配任意小写字母。

边界匹配

  • ^:匹配字符串的开头。
  • $:匹配字符串的结尾。
  • \b:匹配单词的边界。
  • \B:匹配非单词的边界。

分组和捕获

  • ():分组,将多个字符作为一个整体,并捕获分组中的内容。
  • (?:):非捕获组,将多个字符作为一个整体,但是不捕获分组中的内容。

特殊字符

  • \:转义字符,用于匹配特殊字符本身。
  • .:匹配任意字符(除了换行符)。
  • |:用于指定多个模式的选择。
  • \d:匹配任意数字字符 等价于 [0-9]
  • \D:匹配任意非数字字符 等价于 [^0-9]
  • \w:匹配任意字母、数字或下划线字符 等价于[a-zA-Z0-9_]
  • \W:匹配任意非字母、数字或下划线字符 等价于 [^a-zA-Z0-9_]
  • \s:匹配任意空白字符(空格、制表符、换行符等)。
  • \S:匹配任意非空白字符。

贪婪与非贪婪量词

默认情况下,量词(*, +, ?, {})是贪婪的,会尽可能多地匹配字符。在量词后加?可使其变为非贪婪(懒惰)模式:

  • *?:匹配零次或多次,但是尽可能少地匹配。
  • +?:匹配一次或多次,但是尽可能少地匹配。
  • ??:匹配零次或一次,但是尽可能少地匹配。
  • {n}?:匹配恰好 n 次,但是尽可能少地匹配。
  • {n,}?:匹配至少 n 次,但是尽可能少地匹配。
  • {n,m}?:匹配至少 n 次且不超过 m 次,但是尽可能少地匹配。

预查|断言

预查只判断是否满足那些条件,不会进行匹配,也不会进行捕获。

  • (?=):正向预查,判断后面存在 xxx。例如:windows(?=98|99) 判断 windows 后面包含 98 或者 99,
  • (?!):负向预查,判断后面不存在 xxx。例如: windows(?!98|99) 判断 windows 后面不包含 98 或者 99
  • (?<=):正向后查,判断前面存在 xxx 例如:(?<=98|99)windows 判断 windows 前面包含 98 或者 99
  • (?<!):负向后查,判断前面不存在 xxx。 例如:(?<!98|99)windows 判断 windows 前面不包含 98 或者 99

修饰符

常用修饰符

  • i(ignore case):忽略大小写。
  • g(global):全局匹配,匹配所有符合条件的内容。
  • m(multiline):多行匹配。
  • s(dotall):匹配任意字符(包括换行符)。
  • u(unicode):匹配 Unicode 字符。
  • x(verbose):允许在正则表达式中使用注释和空白字符。

组合修饰符

  • gi:全局匹配+忽略大小写
  • ims:忽略大小写+多行模式+点号匹配换行符

案例讲解

匹配手机号

  • 手机号规则:以 1 开头的 11 位数字,
  • 正则规则:/^1[0-9]{10}$/
  • 规则说明:
    • ^1:匹配以 1 开头的字符串
    • [0-9]{10}:匹配 10 位数字
    • $:匹配字符串的结尾
python
import re
pattern = r'^1[0-9]{10}$'
string = '13812345678'
match_obj = re.match(pattern, string)
print(match_obj)  # <re.Match object; span=(0, 11), match='13812345678'>

匹配邮箱

  • 邮箱规则: 任意字符+@+任意字符+.+任意字母 2-8 位
  • 正则规则:^[a-zA-Z0-9_]+@[a-zA-Z0-9_]+\.[a-zA-Z0-9]_+$
  • 规则说明:
    • ^[a-zA-Z0-9_]+:匹配以字母、数字或下划线开头的字符串 至少一个
    • @: 匹配@
    • [a-zA-Z0-9_]+: 匹配@后面的字符串 至少一个
    • \. 匹配.
    • [a-zA-Z0-9_]+:匹配.后面的任意字符 至少一个
    • $:匹配字符串的结尾
python
import re
pattern = r'^[a-zA-Z0-9_]+@[a-zA-Z0-9_]+\.[a-zA-Z0-9_]+$'
string = 'job@163.com'
match_obj = re.match(pattern, string)
print(match_obj)  # <re.Match object; span=(0, 11), match='job@163.com'>

匹配强密码

  • 强密码规则:
    • 长度在 8-16 位之间
    • 必须包含至少一个大写字母 A-Z
    • 必须包含至少一个小写字母 a-z
    • 必须包含至少一个数字 0-9
    • 必须包含至少一个特殊字符 仅限 !@#$%?
  • 正则规则:^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!@#$%?])[a-zA-Z0-9_!@#$%?]{8,16}$
  • 规则说明:
    • 先进行预查,判断是否满足条件,然后进行匹配
    • (?=.*[a-z]):预查.*后面至少一个小写字母
    • (?=.*[A-Z]:预查.*后面至少一个大写字母
    • (?=.*[0-9]):预查.*后面至少一个数字
    • (?=.*[!@#$%?]):预查.*后面至少一个特殊字符 仅限 !@#$%?
    • [a-zA-Z0-9_!@#$%?]{8,16}:匹配 8-16 位 仅限字母、数字、下划线、特殊字符
python
import re
pattern = r'^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!@#$%?])[a-zA-Z0-9_!@#$%?]{8,16}$'
string = 'a1@384A6#78a'
match_obj = re.match(pattern, string)
print(match_obj)  # <re.Match object; span=(0, 11), match='a1@384A6#78a'>

提取 header 头信息

python
import re
line = '''From: author@example.com
User-Agent: Thunderbird 1.5.0.9 (X11/20061227)
MIME-Version: 1.0
Content-Type: application/json
To: editor@example.com'''

pattern = r'(.*):(.*)'
match_obj = re.findall(pattern, line)
print(match_obj)  # [('From', ' author@example.com'), ('User-Agent', ' Thunderbird 1.5.0.9 (X11/20061227)'), ('MIME-Version', ' 1.0'), ('Content-Type', ' application/json'), ('To', ' editor@example.com')]

匹配 HTML 标签

  • 规则:<标签名>内容</标签名>
  • 正则规则:<\w+\b>.*</\w+\b>
  • 规则说明:
    • <\w+\b>:匹配以<开头,后面跟着字母、数字或下划线的单词,最后以>结尾的字符串
    • .*:匹配任意字符(包括换行符)
    • </\w+\b>:匹配以</开头,后面跟着字母、数字或下划线的单词,最后以>结尾的字符串
python
import re
pattern = r'<\w+\b>.*</\w+\b>'
string = '<div>内容</div>'
match_obj = re.match(pattern, string)
print(match_obj)  # <re.Match object; span=(0, 14), match='<div>内容</div>'>