正则表达式 RegEx

0x01 概述

  • 正则表达式(RegEx)可以精确描述需要匹配的字符组合,提高文本处理效率
  • 相关工具:
    • 正则表达式在线测试网站:https://regexr.com/
    • VSCode 插件:Regex Previewer
    • Python 的 re 模块:import re

0x02 基本语法

(1)字符匹配

  • 正则表达式一般用两个 / 包裹起来,在后面跟上修饰符

    修饰符 说明
    g global,全局
    i case insensitive,不区分大小写
    m multiline,多行
    s single line(dotall),单行
    u unicode,Unicode 字符
    y sticky,只读
  • . 表示除了换行符外的任意一个字符

    • /.al/g:全局中,以任意字符开头并以 al 结尾的文本,如 special 中的 ial
    • /a.l/g:全局中,以 a 开头、l 结尾并中间包含任意字符的文本,如 all
    • /al./g:全局中,以 al 开头并以任意字符结尾的文本,如 always 中的 alw
  • [] 表示匹配指定字符的集合,其中可以使用 - 表示字符范围

    • /al[lw]/g:全局中,以 al 开头并且后面的字符为 l 或 w 的文本
    • /al[l-w]/g:全局中,以 al 开头并且后面的字符为 l 到 w 之间的文本
    • /al[l-wL-W]/g:全局中,以 al 开头并且后面的字符为 l 到 w 之间或 L 到 W 之间的文本
    • /al[l-w0-9]/g:全局中,以 al 开头并且后面的字符为 l 到 w 之间或 0 到 9 之间的文本
  • ^[] 内表示匹配指定字符以外的集合[] 的取反)

    • /al[^l-w]/g:全局中,以 al 开头并且后面的字符不在 l 和 w 之间的文本

(2)预定义的字符类

  • 预定义的字符类用于匹配一些常见的字符
  • \d 表示数字,等同于 [0-9];而 \D 是取反,等同于 [^0-9]
    • /SR[0-9]/g 可写为 /SR\d/g
  • \w 表示字母、数字或下划线,等同于 [a-zA-z0-9_];而 \W 是取反
  • \s 表示空白字符,即空格、制表符(Tab);而 \S 是取反

0x03 位置与边界匹配

  • ^ [] 内表示匹配指定字符开头的行
    • /^a/g:全局中,第一个以 a 开头的行
    • /^a/gm:全局中,所有以 a 开头的行(修饰符 m 表示多行匹配
  • $ 表示匹配指定字符结尾的行
    • /a$/g:全局中,以 a 结尾的行
    • /\.$/g:全局中,以 . 结尾的行(由于 . 在正则表达式中是特殊符合,需要使用 \ 转义)
  • \b 表示匹配指定字符开头的单词;而 \B 是取反
    • /\bal/g:全局中,以 al 开头的单词,如 always、all 等,但不包括如 special、specially 等
    • /al\b/g:全局中,以 al 结尾的单词,如 special 等,但不包括如 specially 等
    • /\bal\b/g:全局中的单词 al
    • /\Bal\B/g:全局中,中间包含 al 的单词,如 specially

0x04 量词

  • + 表示匹配指定字符出现一次或多次
    • /es+/g:全局中,匹配 e 开头并出现一次或多次 s 的单词,如 expression
  • * 表示匹配指定字符出现零次或多次
    • /es*/g:全局中,匹配 e 开头并出现零次或多次 s 的单词,如 create
  • {} 表示匹配指定字符出现指定次数
    • /es{2}/g:全局中,匹配 e 开头并出现 2 次 s 的单词,如 expression
    • /es{1,3}/g:全局中,匹配 e 开头并出现 1 到 3 次 s 的单词
    • /es{2,}/g:全局中,匹配 e 开头并出现至少 2 次 s 的单词
      • 正则表达式默认是贪婪匹配
  • ? 表示匹配时满足最小匹配条件,即非贪婪匹配
    • /es{2,}?/g:全局中,匹配出现 2 次且仅 2 次 es 的单词

0x05 分组、捕获、引用

  • () 表示分组,可以将多个字符作为整体来处理

    • /(es)*/g:全局中,匹配出现零次或多次 es 的单词,如 create
    • /(N|n)ame/g:全局中,匹配 Name 或 name
  • 分组捕获

    1. 文本内容:

      2000-1-1
      2001/02/02
      2003.3.3
      2004_4_04
      20050505
      
    2. 正则表达式:/(\d{4})[-/._]?(\d{1,2})[-/._]?(\d{1,2})[-/._]?/gm

    3. 分别捕获年($1)、月($2)、日($3

    4. 使用 : 取消捕获:(?:\d{1,2})

  • 分组引用

    1. 文本内容:

      america
      bob
      google
      
    2. 正则表达式:/([a-z])[a-z]*\1/g

      • ([a-z]) 第一个字符,并分组
      • [a-z]* 中间任意个字符
      • \1 第一组的字符
    3. 此时会匹配出首尾相同的字符串文本,如 america、bob、goog

0x06 前瞻和后顾

  • 前瞻和后顾是特殊的匹配方式,按照是否匹配可分为正向前瞻、负向前瞻、正向后顾、负向后顾

案例文本内容:

$123
$456
$abc
$def
  • 正向前瞻 =/\$(?=\d+)/g,此时匹配 $123\(456* 的 *\)
  • 负向前瞻 !/\$(?!\d+)/g,此时匹配 \(abc* 和 *\)def$
  • 正向后顾 <=/(?<=\$)\d+/g,此时匹配 $123$456123456
  • 负向后顾 <!/(?<!\$)\d+/g,此时匹配 $123$4562356

正则表达式版本问题

  • POSIX 基本(BRE)
  • POSIX 扩展(ERE)
  • Perl 兼容正则表达式(PCRE)
  • 其他版本(Python、Java、JavaScript 等)

-End-

posted @ 2024-05-06 11:22  SRIGT  阅读(47)  评论(0编辑  收藏  举报