正则表达式关键词解析
字数 1188 2025-08-15 21:33:22

正则表达式高级特性详解

子模式 (Subpatterns)

子模式是通过 () 将正则表达式的某部分括起来形成的,分为两种类型:

  1. Capturing (捕获匹配)

    • 系统会保存子模式的匹配结果
    • 可用于后向引用
    • 示例:(\d{4})-(\d{2})-(\d{2}) 捕获年、月、日
  2. Non-Capturing (非捕获匹配)

    • 系统不保存子模式匹配结果
    • 主要用于限制条件
    • 包括:正向预查、反向预查等

后向引用 (Backreferences)

后向引用允许引用前面已匹配的子模式:

  • 查找时语法:\数字(如 \1 引用第一个子模式)
  • 替换时语法:$数字(如 $1 引用第一个子模式)

示例:

var str = "2021-01-15";
var pattern = /(\d{4})-(\d{2})-(\d{2})/;
str.replace(pattern, '$2/$3/$1'); // 结果为 "01/15/2021"

预查 (Lookaround)

预查都是非获取匹配,不消耗字符,匹配发生后立即开始下一次搜索。

正向预查 (Lookahead)

  1. 正向肯定预查 (?=pattern)

    • 预测后面必须匹配 pattern
    • 示例:匹配带 ing 的单词但不要 ing
    var con = "coming soon,going gogogo";
    var reg = /\b[\w]+(?=ing\b)/g;
    con.match(reg); // ["com", "go"]
    
  2. 正向否定预查 (?!pattern)

    • 预测后面必须不匹配 pattern

反向预查 (Lookbehind)

  1. 反向肯定预查 (?<=pattern)

    • 预测前面必须匹配 pattern
    • pattern 长度必须固定
  2. 反向否定预查 (?<!pattern)

    • 预测前面必须不匹配 pattern

示例:数字千位分隔符

var number = "82359123650916359816359";
var regex = /(?<=\d)(?=(\d{3})+$)/g;
number.replace(regex, ","); // "82,359,123,650,916,359,816,359"

捕获与非捕获

  • 捕获组 (pattern):匹配内容会被存储,可通过 \数字$数字 引用
  • 非捕获组 (?:pattern):匹配内容不会被存储,提高性能
    var reg1 = /windows(?:2000|NT|98)/i;
    var reg2 = /windows(2000|NT|98)/i;
    var str = 'windows2000';
    str.match(reg1); // ["windows2000", ...]
    str.match(reg2); // ["windows2000", "2000", ...]
    

贪婪与懒惰匹配

  • 贪婪匹配:默认行为,匹配尽可能多的字符

    • 示例:a.*b 匹配 aabab 整个字符串
  • 懒惰匹配:在量词后加 ?,匹配尽可能少的字符

    • 示例:a.*?b 匹配 aabab 得到 aabab

位置匹配

匹配位置而不获取字符:

代码/语法 说明
\b 单词边界
^ 字符串开始
$ 字符串结束
\B 非单词边界
(?=exp) 后面是 exp 的位置
(?!exp) 后面不是 exp 的位置
(?<=exp) 前面是 exp 的位置
(?<!exp) 前面不是 exp 的位置

关键区别

  1. (?:pattern) 与预查的区别:

    • (?:pattern) 会消耗字符
    • 预查不消耗字符
  2. 反向预查要求 pattern 长度固定,正向预查无此限制

  3. 捕获组会存储匹配内容,非捕获组不会

  4. 贪婪匹配尽可能多,懒惰匹配尽可能少

掌握这些高级特性可以编写更精确、高效的正则表达式,解决复杂的文本处理问题。

正则表达式高级特性详解 子模式 (Subpatterns) 子模式是通过 () 将正则表达式的某部分括起来形成的,分为两种类型: Capturing (捕获匹配) 系统会保存子模式的匹配结果 可用于后向引用 示例: (\d{4})-(\d{2})-(\d{2}) 捕获年、月、日 Non-Capturing (非捕获匹配) 系统不保存子模式匹配结果 主要用于限制条件 包括:正向预查、反向预查等 后向引用 (Backreferences) 后向引用允许引用前面已匹配的子模式: 查找时语法: \数字 (如 \1 引用第一个子模式) 替换时语法: $数字 (如 $1 引用第一个子模式) 示例: 预查 (Lookaround) 预查都是非获取匹配,不消耗字符,匹配发生后立即开始下一次搜索。 正向预查 (Lookahead) 正向肯定预查 (?=pattern) 预测后面必须匹配 pattern 示例:匹配带 ing 的单词但不要 ing 正向否定预查 (?!pattern) 预测后面必须不匹配 pattern 反向预查 (Lookbehind) 反向肯定预查 (?<=pattern) 预测前面必须匹配 pattern pattern 长度必须固定 反向否定预查 (?<!pattern) 预测前面必须不匹配 pattern 示例:数字千位分隔符 捕获与非捕获 捕获组 (pattern) :匹配内容会被存储,可通过 \数字 或 $数字 引用 非捕获组 (?:pattern) :匹配内容不会被存储,提高性能 贪婪与懒惰匹配 贪婪匹配 :默认行为,匹配尽可能多的字符 示例: a.*b 匹配 aabab 整个字符串 懒惰匹配 :在量词后加 ? ,匹配尽可能少的字符 示例: a.*?b 匹配 aabab 得到 aab 和 ab 位置匹配 匹配位置而不获取字符: | 代码/语法 | 说明 | |----------|------| | \b | 单词边界 | | ^ | 字符串开始 | | $ | 字符串结束 | | \B | 非单词边界 | | (?=exp) | 后面是 exp 的位置 | | (?!exp) | 后面不是 exp 的位置 | | (?<=exp) | 前面是 exp 的位置 | | (?<!exp) | 前面不是 exp 的位置 | 关键区别 (?:pattern) 与预查的区别: (?:pattern) 会消耗字符 预查不消耗字符 反向预查要求 pattern 长度固定,正向预查无此限制 捕获组会存储匹配内容,非捕获组不会 贪婪匹配尽可能多,懒惰匹配尽可能少 掌握这些高级特性可以编写更精确、高效的正则表达式,解决复杂的文本处理问题。