正则表达式极简入门教程

—— 专为正则新手 + 在线测试工具设计

建议你一边看一边在你的网站测试工具里动手试,每一节都会给出可以直接复制的“正则 + 测试文本”。


0. 使用说明与学习建议

0.1 这篇文档适合谁?

  • 完全不会正则,只听说过这个词
  • 只会在编辑器里用 abc 搜索,不会写复杂一点的规则
  • 想在你的“正则测试网站”里边试边学

0.2 需要的前置知识

  • 会打字,会复制粘贴
  • 大概知道“字符串”“文本”是什么
    不需要会编程,本教程不依赖任何编程语言。

0.3 如何使用这篇文档?

  1. 打开你的正则测试网站。
  2. 每一小节我都会给出:
    • 正则表达式:粘贴到“正则输入框”
    • 测试文本:粘贴到“测试文本框”
    • 有时还会给出替换模板:粘贴到“替换输入框”
  3. 点击“测试 / 替换”,观察高亮和结果。

1. 正则表达式是什么?

1.1 正则表达式的概念:什么是“模式匹配”?

可以把正则表达式想象成字符串的模具

  • 普通搜索:
    你在文档里搜“苹果”,只能找到完全等于“苹果”的地方。
  • 正则搜索:
    你可以搜“所有看起来像手机号的东西”,比如:
    • 1 开头
    • 后面跟着 10 位数字
      不管是 13800138000 还是 19987654321,都能一次性找出来。

模式匹配就是:

用一小段“规则字符串”(正则表达式),去匹配一大段文本中“符合这个规则的部分”。

在你的工具里试一试

  1. 正则输入框:
    regex
    abc
  2. 测试文本框:
    text
    abc
    xyzabc123
    aabbcc
  3. 观察:哪些地方被高亮了?
    • 第一行:整行 abc
    • 第二行:中间的 abc
    • 第三行:没有完全连续的 abc,所以不匹配

这就是最简单的“字面量匹配”。


1.2 正则能解决什么问题?(查找 / 替换 / 校验)

① 查找(搜索)

场景:从一堆文本里找出所有手机号。

  1. 正则输入框:
    regex
    1\d{10}
  2. 测试文本框:
    text
    正确:13800138000
    错误:128abc
    匹配:19987654321
    还有:10086
  3. 观察:只要是“1 + 10 位数字”的地方都会被高亮。

这里的 \d{10} 先不用管细节,你可以先理解为“10 位数字”。


② 替换(重点:固定替换 + 分组模板替换)

替换是你的网站上非常重要的功能,尤其是分组模板替换$1$2 这种)。

2.1 固定文本替换

需求:把所有 foo 换成 bar

  1. 正则输入框:
    regex
    foo
  2. 替换模板输入框:
    text
    bar
  3. 测试文本框:
    text
    foo
    foo123
    123foo456
    没有这个词
  4. 点击“替换”,你会看到:
    text
    bar
    bar123
    123bar456
    没有这个词

这是最基础的“固定文本替换”。


2.2 分组模板替换(李四$2 这种)

分组模板替换的核心思想:

  1. 用括号 () 把你想“记住”的部分圈出来,这叫分组
  2. 每个分组会自动编号:第一个是 $1,第二个是 $2,以此类推。
  3. 在“替换模板”里,用 $1$2 来引用这些分组的内容,重新组合。

看你给的截图,大概是这样的场景:

  • 文本里有很多行:某某: 13800138000
  • 你用正则把“名字”和“号码”分成两组
  • 然后在替换模板里写:李四$2,就能把所有名字都改成“李四”,但保留原来的号码。

我们来完整走一遍。

示例 1:把“张三: 13800138000”变成“李四13800138000”

  1. 正则输入框:

    regex
    (\S+):\s*(\d+)

    含义先简单记住:

    • (\S+):第 1 组,匹配“连续的非空白字符” → 名字
    • ::一个冒号
    • \s*:0 个或多个空白(空格、制表符等)
    • (\d+):第 2 组,匹配“连续的数字” → 手机号
  2. 测试文本框:

    text
    张三: 13800138000
    李四 : 13912345678
    王五:12345664123
    赵六:这个是全角冒号,不会被匹配
  3. 替换模板输入框(重点):

    text
    李四$2
  4. 点击“替换”,你会得到:

    text
    李四13800138000
    李四13912345678
    李四12345664123
    赵六:这个是全角冒号,不会被匹配

这里发生了什么?

  • $1:原来的名字(张三 / 李四 / 王五)
  • $2:原来的手机号
  • 替换模板写的是 李四$2
    • 不管原来是谁,名字都改成“李四”
    • $2 保留原来的手机号

这就是你截图里“李四$2”的典型用法。


示例 2:把“张三: 13800138000”变成“13800138000(张三)”

  1. 正则输入框:
    regex
    (\S+):\s*(\d+)
  2. 替换模板输入框:
    text
    $2($1)
  3. 测试文本同上。

替换结果:

text
13800138000(张三)
13912345678(李四)
12345664123(王五)
赵六:这个是全角冒号,不会被匹配

你可以在你的网站上预设几个常用模板,比如:

  • $1的电话是$2
  • 联系人:$2($1)
  • 李四$2(批量改名)

③ 校验格式(验证)

校验就是判断“整个字符串是不是符合某种格式”。

比如:严格判断一个字符串是不是“11 位中国手机号”。

  1. 正则输入框:
    regex
    ^1[3-9]\d{9}$
  2. 测试文本框:
    text
    13912345678
    123456
    23987654321
    19987654321
    abc13800138000
  3. 如果你的工具支持“逐行校验”,你会看到:
    • 13912345678 ✅ 匹配
    • 19987654321 ✅ 匹配
    • 其他行 ❌ 不匹配

这里的 ^$ 是“开头”和“结尾”的意思,后面会详细讲。


1.3 小测验:边学边练

在你的工具里完成下面两个小任务:

任务 1:日期格式转换

目标
2023-08-15 转成 15/08/2023

  1. 正则输入框:
    regex
    (\d{4})-(\d{2})-(\d{2})
  2. 替换模板输入框:
    text
    $3/$2/$1
  3. 测试文本框:
    text
    2023-08-15
    1999-12-31
    2025-01-01

观察结果是否变成:

text
15/08/2023
31/12/1999
01/01/2025

任务 2:密码强度简单检查

要求:至少 8 位,必须同时包含:

  • 小写字母
  • 大写字母
  • 数字
  1. 正则输入框:
    regex
    ^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).{8,}$
  2. 测试文本框:
    text
    abc123
    Abc12345
    abcdefgh
    ABCD1234
    aB1aB1aB1

观察:

  • Abc12345aB1aB1aB1
  • 其他 ❌

这个正则稍微有点难,先知道“可以做到这种效果”就行,后面学到“预查”时会再解释。


2. 正则的最基础概念

2.1 字面量匹配

字面量匹配就是:

正则里写什么,就去文本里找一模一样的东西。

例子:

  1. 正则输入框:
    regex
    hello
  2. 测试文本框:
    text
    hello
    Hello
    hello world
    world hello
  3. 结果:
    • 匹配:hellohello world 中的 helloworld hello 中的 hello
    • 不匹配:Hello(大小写不同)

2.2 元字符与普通字符

在正则里,字符分两类:

  • 普通字符:自己就是自己
    比如:ab1
  • 元字符:有特殊含义
    比如:. ^ $ * + ? [] () | \

举个例子:

  • .(点)不是“句号”,而是“匹配任意一个字符(除了换行)”
  • * 不是星号,而是“重复 0 次或多次”

后面我们会一个个讲,现在只要知道:

看到这些符号,要小心,它们可能不是字面意思。


2.3 转义:让元字符“变回普通字符”

如果你想匹配一个真正的点号 .,而不是“任意字符”,怎么办?

答案:转义,在前面加反斜杠 \

  • .:任意一个字符
  • \.:字面上的点号

在你的工具里试试:

  1. 正则输入框:
    regex
    .
  2. 测试文本框:
    text
    a
    1
    .
    中

你会发现每一行的那个字符都会被匹配。

再试:

  1. 正则输入框:
    regex
    \.
  2. 测试文本同上。

这次只有第三行的 . 会被匹配。

同理,如果你想匹配 *?() 等元字符,也要加 \

  • \* 匹配星号
  • \? 匹配问号
  • \( 匹配左括号
  • \) 匹配右括号

3. 字符类与范围

3.1 字符类基础:[]

[] 表示“一组可选字符中的任意一个”。

  • [abc]:匹配 abc 中的任意一个字符
  • [01]:匹配 01

在你的工具里试:

  1. 正则输入框:
    regex
    [abc]
  2. 测试文本框:
    text
    a
    b
    c
    d
    abcd

你会看到所有的 abc 都被高亮。


3.2 范围:[0-9][a-z]

[] 里可以用 - 表示范围:

  • [0-9]:0 到 9 的任意数字
  • [a-z]:小写字母 a 到 z
  • [A-Z]:大写字母 A 到 Z
  • [a-zA-Z0-9]:字母或数字

试一试:

  1. 正则输入框:
    regex
    [0-9]
  2. 测试文本框:
    text
    0
    5
    9
    a
    123abc456

你会看到所有数字都被匹配。


3.3 取反字符类:[^ ]

[] 里,如果第一个字符是 ^,表示“不在这组里的任意一个字符”。

  • [^0-9]:不是数字的任意一个字符
  • [^a-zA-Z]:不是字母的任意一个字符

注意:

^[] 里面和在外面含义不同。

  • [] 里面开头:取反
  • 在外面:表示“开头”(后面会讲)

试一试:

  1. 正则输入框:
    regex
    [^0-9]
  2. 测试文本框:
    text
    0
    5
    9
    a
    #
    1a2b3c

你会看到所有“非数字”的字符被高亮。


3.4 预定义字符类:\d\w\s

为了方便,正则里内置了一些常用的“快捷写法”:

  • \d:digit,数字,相当于 [0-9]
  • \w:word,单词字符,相当于 [A-Za-z0-9_]
  • \s:space,空白字符(空格、制表符、换行等)

对应的反义:

  • \D:非数字,相当于 [^0-9]
  • \W:非单词字符
  • \S:非空白字符

试一试:

  1. 正则输入框:
    regex
    \d\d\d
  2. 测试文本框:
    text
    123
    12a
    a12
    4567

你会看到:

  • 123 整个匹配
  • 4567 中的 456 匹配

3.5 小练习

  1. 匹配“任意 3 位数字”:
    regex
    \d{3}
  2. 匹配“只包含字母和数字的 5 位字符串”(整行):
    regex
    ^[A-Za-z0-9]{5}$

4. 量词:控制重复次数

量词用来表示“前面的东西重复多少次”。

4.1 基本量词:*+?

  • *:0 次或多次
    例:a* 可以匹配:空字符串、aaaaaa……
  • +:1 次或多次
    例:a+ 可以匹配:aaaaaa……(但不能是空)
  • ?:0 次或 1 次
    例:a? 可以匹配:空字符串、a

试一试:

  1. 正则输入框:
    regex
    a*
  2. 测试文本框:
    text
    ""
    a
    aa
    baac

你会看到很多地方都能匹配到(包括空位置),先感受一下,后面会讲更精确的写法。


4.2 精确与范围量词:{m}{m,}{m,n}

  • {3}:恰好 3 次
    例:\d{3} → 3 位数字
  • {2,}:至少 2 次
    例:a{2,}aaaaaaaaa……
  • {2,5}:2 到 5 次
    例:\d{2,5} → 2~5 位数字

试一试:

  1. 正则输入框:
    regex
    a{2,4}
  2. 测试文本框:
    text
    a
    aa
    aaa
    aaaa
    aaaaa

观察每一行被匹配的部分。


4.3 贪婪与惰性(了解)

默认情况下,量词是贪婪的

能多匹配就多匹配。

  • .*:尽可能多地匹配任意字符
  • .*?:尽可能少地匹配任意字符(惰性)

试一试:

  1. 正则输入框:
    regex
    <.*>
  2. 测试文本框:
    text
    <a>123<b>456</b>

你会发现,它会从第一个 < 一直匹配到最后一个 ><a>123<b>456</b>

改成惰性:

  1. 正则输入框:
    regex
    <.*?>

你会看到:

  • <a>
  • <b>
  • </b>
    被分别匹配。

4.4 小练习

  1. 匹配“11 位手机号”(简单版):
    regex
    1\d{10}
  2. 匹配“6~16 位,只包含字母数字下划线的密码”(整行):
    regex
    ^\w{6,16}$

5. 边界与锚点:限定位置

5.1 行/字符串边界:^$

  • ^:开头
  • $:结尾

^abc$ 表示:整行必须是 abc,前后不能有别的东西。

试一试:

  1. 正则输入框:
    regex
    ^\d+$
  2. 测试文本框:
    text
    123
    123a
    a123
    12 34

只有第一行会被完全匹配。


5.2 单词边界:\b\B

  • \b:单词边界(字母数字下划线 与 其他字符 的交界处)
  • \B:非单词边界

例子:

  1. 正则输入框:
    regex
    \bcat\b
  2. 测试文本框:
    text
    cat
    a cat b
    concatenate
    cat123
    123cat

你会看到:

  • 匹配:cata cat b 中的 cat
  • 不匹配:concatenatecat123123cat

5.3 常见组合

  • ^[0-9]+$:整行都是数字
  • ^https?://:以 http://https:// 开头

试一试:

  1. 正则输入框:
    regex
    ^https?://
  2. 测试文本框:
    text
    http://example.com
    https://example.com
    ftp://example.com
    example.com

6. 分组与捕获:给匹配“分块”

6.1 分组基础:( )

() 可以把一部分内容当成一个整体:

  • (abc)+abc 这个整体重复 1 次或多次
    可以匹配:abcabcabcabcabcabc……

试一试:

  1. 正则输入框:
    regex
    (ab)+
  2. 测试文本框:
    text
    ab
    abab
    ababab
    aabb

6.2 捕获组与编号:$1、$2

前面在“分组模板替换”里已经用过:

  • 第 1 个 ()$1
  • 第 2 个 ()$2

再回顾一下“日期重排”:

  1. 正则输入框:
    regex
    (\d{4})-(\d{2})-(\d{2})
  2. 替换模板:
    text
    $3/$2/$1

6.3 非捕获分组:(?: )(了解)

有时候你只想用括号来“分组”,但不想产生 $1$2 这种编号,就可以用:

regex
(?:ab|cd)

它的作用和 (ab|cd) 一样,只是不会产生捕获组编号。


6.4 小练习

  1. 2025-12-04 中提取年、月、日(用上面的日期正则)。
  2. 匹配 colorcolour
    regex
    colou?r
    或者:
    regex
    colou?r

7. 选择:|(或)

7.1 基本用法

  • cat|dog:匹配 catdog
  • (ab|cd)ef:匹配 abefcdef

试一试:

  1. 正则输入框:
    regex
    cat|dog
  2. 测试文本框:
    text
    cat
    dog
    catdog
    bird

7.2 优先级与括号

  • ab|cd:匹配 abcd
  • a(b|c)d:匹配 abdacd

7.3 小练习

  1. 匹配以 .jpg / .png / .gif 结尾的文件名:
    regex
    \.(jpg|png|gif)$
  2. 匹配 yesno(忽略大小写,可以用工具的 i 标志):
    regex
    ^(yes|no)$

8. 回溯引用:引用前面匹配的内容

8.1 基本概念

\1\2 表示“引用前面第 1、2 个捕获组的内容”。

例子:匹配重复单词:

  1. 正则输入框:
    regex
    (\b\w+\b)\s+\1
  2. 测试文本框:
    text
    hello hello
    test test
    hello world

8.2 常见应用

  1. 匹配成对的引号内容:

    regex
    (["']).*?\1

    可以匹配 "abc"'abc'

  2. 匹配重复数字:

    regex
    (\d)\1+

    可以匹配:112223333……


8.3 小练习

  1. 匹配连续出现两次的单词(如 hello hello)。
  2. 匹配形如 aabbbcccc 这类同一字符重复的字符串(整行):
    regex
    ^(\w)\1+$

9. 前后预查(进阶但常用)

本章稍微进阶一点,看不懂可以先跳过,等用到时再回来。

9.1 零宽断言的概念

预查的特点:

  • 只“看一眼”前后是不是符合条件
  • 不真正“吃掉”字符

9.2 正向预查:(?=...)

例:匹配“后面跟着数字的单词”:

regex
\w+(?=\d)

例:匹配以 .jpg 结尾的文件名,但不包含 .jpg 本身:

regex
\w+(?=\.jpg)

9.3 负向预查:(?!...)

例:匹配“后面不是数字的单词”:

regex
\w+(?!\d)

9.4 后向预查:(?<=...) / (?<!...)(部分引擎不支持)

例:匹配“前面是 ¥ 的数字”:

regex
(?<=¥)\d+

9.5 小练习

  1. 匹配“前面是 @ 的用户名”(不包含 @):
    regex
    (?<=@)\w+
  2. 匹配“不以 0 开头的数字串”(简单版):
    regex
    ^(?!0)\d+$

10. 常见实战案例(综合应用)

10.1 校验类

邮箱(简化版)

regex
^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$

手机号(中国常见号段简化版)

regex
^1[3-9]\d{9}$

简单 URL(不追求标准)

regex
^https?://[^\s/$.?#].[^\s]*$

10.2 文本提取类

从日志中提取 IP 地址

regex
\b\d{1,3}(\.\d{1,3}){3}\b

从 HTML 片段中提取 href(仅演示)

regex
href="([^"]*)"

提醒:复杂 HTML 不建议用正则完整解析。


10.3 替换与重排

日期重排(再复习一次):

regex
(\d{4})-(\d{2})-(\d{2})

替换模板:

text
$3/$2/$1

批量给数字加千分位逗号(简单示例)
(不同引擎支持度不同,这里只是展示思路)

regex
(\d)(?=(\d{3})+(?!\d))

替换模板:

text
$1,

11. 不同语言中的正则差异(概览)

你的网站是“在线测试工具”,用户可能来自不同语言,这里简单提一下。

11.1 通用核心 vs 方言特性

  • 本文讲的 . ^ $ * + ? [] () | \d \w \s 等,大部分语言都支持。
  • 某些高级特性(如后向预查、命名分组)不同语言支持情况不同。

11.2 常见标志位(flags)

在你的工具里,通常会有一个“标志位”输入框,比如:

  • i:忽略大小写
  • g:全局匹配(找出所有匹配)
  • m:多行模式(^$ 匹配每一行的开头和结尾)
  • s:单行模式(. 可以匹配换行)

12. 正则调试与优化

12.1 调试思路

  • 从简单开始,逐步加复杂度
  • 每加一小段,就在你的工具里测试一次
  • 用括号把结构分清楚

12.2 性能与“灾难性回溯”(入门级)

有些写法会让正则引擎“反复试探”,速度非常慢,比如:

regex
(a+)+$

在真实项目里要尽量避免嵌套的“模糊量词”(*+{m,})组合。


13. 编写可读正则的技巧

13.1 命名捕获组(如果引擎支持)

有些引擎支持:

regex
(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})

这样在代码里可以用 yearmonthday 来访问。


13.2 给正则写“文档”

  • 在旁边写注释,说明这个正则是干什么的
  • 给出 2~3 个“通过示例”和“失败示例”

14. 常用正则速查表

14.1 常用模式片段

  • 数字:\d
  • 非数字:\D
  • 单词字符:\w
  • 空白字符:\s
  • 任意字符(除换行):.
  • 行首 / 行尾:^ / $

14.2 常用格式

  • 11 位手机号(简化):
    regex
    ^1[3-9]\d{9}$
  • 邮箱(简化):
    regex
    ^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$
  • 日期 YYYY-MM-DD
    regex
    ^\d{4}-\d{2}-\d{2}$

15. 后续进阶方向

  • 更复杂的预查、条件判断、递归模式(部分引擎)
  • Unicode 匹配(\p{Han} 等)
  • 学习更系统的书籍,如《精通正则表达式》