正则表达式

正则表达式

正则表达式(Regular Expression,简称 regex 或 regexp)是一种用来匹配、查找、替换文本的强大工具,广泛用于编程、文本处理、数据验证等场景(如验证邮箱格式、提取日志内容、清洗数据等)。下面从基础到进阶,带你快速掌握核心用法:

一、基础概念:字符与匹配规则

正则表达式通过元字符(有特殊含义的字符)和普通字符(如字母、数字)的组合,描述文本的“模式”。

1. 普通字符:精确匹配

普通字符(如 a123hello)会精确匹配自身
示例:正则 cat 会匹配文本中的 cat 子串(如 catcategory 中的 cat)。

2. 元字符:特殊含义的字符

元字符是正则的“核心语法”,常用元字符及含义:

元字符 含义 示例 匹配效果
. 匹配任意单个字符(除换行符 \n,若开启多行模式也可匹配换行)。 a.c 匹配 abca1ca&c
* 匹配前面的字符/子模式 0 次或多次(贪婪匹配,尽可能多匹配)。 ab*c 匹配 acabcabbbbbc
+ 匹配前面的字符/子模式 1 次或多次(贪婪匹配)。 ab+c 匹配 abcabbbbbc,不匹配 ac
? 匹配前面的字符/子模式 0 次或 1 次;也可用于“非贪婪匹配”(加在 */+ 后)。 ab?c
a.*?c
匹配 acabc
匹配 ac 之间最短的内容(如 abc 中取 abca123c 中取 a123c 里的最短部分)
{n} 匹配前面的字符/子模式恰好 n 次 a{3} 匹配 aaa
{n,} 匹配前面的字符/子模式至少 n 次 a{2,} 匹配 aaaaaaaaa...
{n,m} 匹配前面的字符/子模式至少 n 次,最多 m 次 a{1,3} 匹配 aaaaaa
[] 字符类:匹配括号内的任意单个字符;也可表示范围。 [abc]
[0-9]
匹配 a/b/c
匹配 0-9 的数字
[^] 否定字符类:匹配不在括号内的任意单个字符 [^0-9] 匹配非数字字符(如字母、符号)
^ 锚定符:匹配行的开头(若开启多行模式,匹配每一行的开头)。 ^Hello 匹配以 Hello 开头的行
$ 锚定符:匹配行的结尾(若开启多行模式,匹配每一行的结尾)。 end$ 匹配以 end 结尾的行
() 分组:将多个字符/子模式视为一个整体,可用于“捕获”或“或操作”。 (abc)+
`(a
b)c`
` ` 或操作:匹配左边或右边的子模式。 `cat
\ 转义符:将元字符转义为“普通字符”(如匹配 * 本身需写 \*);也用于预定义字符类(如 \d)。 \*
\d
匹配 *
匹配数字(同 [0-9]
3. 预定义字符类(简化版字符范围)

正则提供了一些简写符号,代替常用的字符范围:

预定义类 等价写法 含义
\d [0-9] 匹配数字
\D [^0-9] 匹配非数字
\w [a-zA-Z0-9_] 匹配“单词字符”(字母、数字、下划线)
\W [^a-zA-Z0-9_] 匹配非单词字符
\s [ \t\n\r\f\v] 匹配空白字符(空格、制表符、换行等)
\S [^ \t\n\r\f\v] 匹配非空白字符

二、进阶用法:分组、捕获与非贪婪匹配

1. 分组与捕获(() 的作用)
  • 分组:将多个字符视为一个整体,配合量词使用。
    示例:(ab)+ 匹配 abababababab…(ab 作为整体重复)。

  • 捕获:分组会“记住”匹配的内容,可通过反向引用\1\2…)在后续复用。
    示例:正则 (\w+) \1 匹配“重复的单词”(如 hello hello),\1 表示引用第一个分组 (\w+) 匹配的内容。

2. 非贪婪匹配(? 的另一种用法)

正则默认是贪婪匹配(尽可能多匹配),加 ? 可改为非贪婪匹配(尽可能少匹配)。

示例:

  • 贪婪:a.*c 匹配 a123c456c 时,会匹配 a123c456c(从第一个 a 到最后一个 c)。
  • 非贪婪:a.*?c 匹配 a123c456c 时,会匹配 a123c(从第一个 a最近的 c)。

三、实战示例:常见场景的正则

1. 验证邮箱格式

需求:匹配常见邮箱(如 user@example.***info123@mail.***)。
正则:^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$
解释:

  • ^\w+:开头是“单词字符”(用户名开头)。
  • ([-+.]\w+)*:用户名中可包含 -+.,且后面跟“单词字符”,重复 0 次或多次。
  • @:匹配 @ 符号。
  • \w+([-.]\w+)*:域名前缀(如 example),可包含 -.
  • \.\w+([-.]\w+)*:域名后缀(如 .***.co.uk),以 . 开头,后跟“单词字符”及可选的 -/.
2. 提取 URL 中的域名

需求:从 https://www.example.***/path?query 中提取 www.example.***
正则:://([^/]+)
解释:

  • ://:匹配 :// 固定字符。
  • ([^/]+):捕获“非 / 的字符”(直到遇到下一个 / 为止),即域名部分。
    在正则 ://([^/]+) 中,://直接匹配 URL 中固定存在的字符串“😕/”,作用是精准定位到域名的起始位置,避免误匹配其他内容。

具体解释:

我们目标是从 URL(如 https://www.example.***/path?query)中提取 www.example.***,而 URL 的结构通常是:
协议://域名/路径?参数
(比如 https://www.example.***/path?query 中,https 是协议,www.example.*** 是域名,/path 是路径)

:// 的核心作用:

它是协议和域名之间的固定分隔符(比如 http://https://ftp:// 中都有 ://)。
正则中先写 ://,就是为了跳过前面的“协议部分”(如 https),直接定位到 :// 后面的内容——这部分才是域名的起始位置。

举例说明:

https://www.example.***/path?query 中:

  • 正则 :// 会精准匹配 https 后面的 :// 这三个字符;
  • 紧接着的 ([^/]+) 就会从 :// 之后开始匹配(即从 www.example.*** 的第一个字符 w 开始),直到遇到第一个 / 为止(www.example.*** 后面的 /),最终捕获 www.example.***

如果没有 ://,直接用 ([^/]+),会匹配什么?
会从 URL 开头开始匹配非 / 的字符,结果会误把 https 也包含进去(比如匹配 https),无法准确定位到域名。

所以,:// 是通过匹配固定分隔符,帮我们“锚定”到域名的起始位置,确保后续的 ([^/]+) 只捕获域名部分。

([^/]+) 是正则中用于精准捕获域名的核心部分,我们拆解来看它的作用:

1. 先看 [^/]:否定字符类,匹配“非 / 的任意字符”

  • [] 表示“字符类”,里面的内容是“允许匹配的字符范围”;
  • ^ 放在 [] 开头时,表示“否定”——即 [^/] 表示“匹配任何不是 / 的字符”(比如字母、数字、.-www 中的 w 等,只要不是 / 都能匹配)。

2. 再看 +:量词,匹配“前面的元素 1 次或多次”

+ 在这里修饰 [^/],表示“连续的、非 / 的字符,至少出现 1 次,最多可以出现任意多次”(只要这些字符中间没有 / 打断)。

3. 整体 ([^/]+):捕获“连续的非 / 字符”

  • 括号 () 是“捕获分组”,作用是把匹配到的内容单独“拎出来”(后续可以提取这个分组的结果,也就是我们要的域名);
  • 结合起来,([^/]+) 会从当前位置开始,连续匹配所有不是 / 的字符,直到遇到第一个 / 为止,然后把这些字符作为一个“分组”捕获下来。

结合 URL 实例看效果

https://www.example.***/path?query 为例:

  • 前面的 :// 已经匹配了 https 后面的 ://,接下来就轮到 ([^/]+) 工作;
  • :// 之后的第一个字符(w)开始,[^/] 会匹配 www.ex……直到遇到 www.example.*** 后面的 /(即 /path 中的 /);
  • 因为 + 要求“至少 1 次”,所以会把 www.example.*** 这一串连续的非 / 字符全部匹配,并用括号捕获——这正是我们需要的域名。

为什么这样写能精准定位域名?

因为 URL 的结构是固定的:协议://域名/路径?参数,其中域名的后面一定跟着第一个 /(比如 www.example.*** 后面是 /path)。
[^/]+ 刚好利用这一点,“贪婪”地匹配所有到第一个 / 为止的非 / 字符,完美圈定域名范围。

如果没有 [^/],比如直接用 .+(匹配任意字符多次),就会把 /path?query 也一起匹配进去,无法单独提取域名。

3. 匹配手机号(以中国大陆为例)

需求:匹配 11 位手机号,开头为 1,第二位为 3/4/5/6/7/8/9。
正则:^1[3-9]\d{9}$
解释:

  • ^1:开头是 1
  • [3-9]:第二位是 3-9 中的一个数字。
  • \d{9}:后面跟 9 位数字。
  • $:行结尾,确保总长度为 11 位。

四、工具推荐:快速测试正则

学习正则时,建议用在线测试工具实时验证效果:

  • regex101:支持多种语言(Python、JavaScript 等),提供详细匹配说明、错误提示。
  • RegExr:可视化正则分组、字符类,适合新手理解。

五、学习建议

  1. 从简单到复杂:先掌握单个元字符(如 .*[]),再组合成复杂模式。
  2. 多实战:找一段文本(如日志、网页源码),用正则尝试匹配、提取目标内容。
  3. 善用工具:用在线工具测试正则,观察匹配过程,理解每一步的作用。

通过以上内容,你已经掌握了正则表达式的核心语法和常见用法,接下来就可以在实际场景中练习啦~

补充:

正则表达式里的 *+? 都属于**“量词元字符”**,用来规定“前面的字符/子表达式出现的次数”,具体含义和示例如下:

1. *(星号)

匹配 前面的字符/子表达式 “0次或多次”(可以不出现,也能出现任意多次)。
示例:
正则 ab*c 中,b 可出现 0 次、1 次或多次,因此能匹配:

  • acb 出现 0 次);
  • abcb 出现 1 次);
  • abbbbbcb 出现多次)。

2. +(加号)

匹配 前面的字符/子表达式 “1次或多次”(至少出现 1 次,不能不出现)。
示例:
正则 ab+c 中,b 至少出现 1 次,因此能匹配:

  • abcb 出现 1 次);
  • abbbbbcb 出现多次);
    不匹配 acb 出现 0 次)。

3. ?(问号)

匹配 前面的字符/子表达式 “0次或1次”(最多出现 1 次,要么没有,要么只有 1 次)。
示例:
正则 ab?c 中,b 最多出现 1 次,因此能匹配:

  • acb 出现 0 次);
  • abcb 出现 1 次);
    不匹配 abbcb 出现 2 次)。

简单记忆:

  • * → “可有可无,多了也能要”;
  • + → “至少有 1 个”;
  • ? → “最多 1 个,没有也可以”。
转载请说明出处内容投诉
CSS教程网 » 正则表达式

发表评论

欢迎 访客 发表评论

一个令你着迷的主题!

查看演示 官网购买