news 2026/5/1 9:42:22

关于正则表达式

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
关于正则表达式

一、前言

正则表达式(Regular Expression,简称 Regex)是一种用于匹配、查找、替换字符串的强大工具,广泛应用于数据验证、日志分析、文本处理等场景。无论是前端表单验证、后端数据清洗,还是爬虫数据提取,正则表达式都能大幅提升开发效率。本文将避开复杂的理论推导,聚焦实用语法 + 场景化案例,帮助开发者快速掌握正则表达式的核心用法。

二、正则表达式基础语法

2.1 核心元字符(必记)

元字符

作用说明

示例

.

匹配任意单个字符(除换行符\n)

a.b 匹配 acb、aab,不匹配 abbc

*

匹配前面的字符 0 次或多次

ab* 匹配 a、ab、abb、abbb

+

匹配前面的字符 1 次或多次

ab+ 匹配 ab、abb,不匹配 a

?

匹配前面的字符 0 次或 1 次(非贪婪匹配)

ab? 匹配 a、ab,不匹配 abb

^

匹配字符串开头

^abc 匹配 abc123,不匹配 xabc

$

匹配字符串结尾

abc$ 匹配 123abc,不匹配 abcx

[]

字符集:匹配其中任意一个字符

[a-zA-Z] 匹配任意大小写字母

[^]

否定字符集:匹配不在其中的字符

[^0-9] 匹配非数字字符

()

分组:将多个字符视为一个整体,可捕获结果

(ab)+ 匹配 ab、abab

|

逻辑或:匹配左右任意一个表达式

a|b 匹配 a 或 b

\

转义字符:匹配元字符本身

a\.b 匹配 a.b,不匹配 acb

2.2 常用预定义字符集(简化书写)

预定义字符

等价写法

作用说明

\d

[0-9]

匹配数字

\D

[^0-9]

匹配非数字

\w

[a-zA-Z0-9_]

匹配字母、数字、下划线

\W

[^a-zA-Z0-9_]

匹配非字母、数字、下划线

\s

[ \t\n\r\f]

匹配空白字符(空格、制表符、换行符等)

\S

[^ \t\n\r\f]

匹配非空白字符

2.3 量词(指定匹配次数)

量词

作用说明

示例

{n}

匹配前面的字符恰好 n 次

a{3} 匹配 aaa,不匹配 aa

{n,}

匹配前面的字符至少 n 次

a{2,} 匹配 aa、aaa、aaaa

{n,m}

匹配前面的字符 n 到 m 次

a{2,3} 匹配 aa、aaa,不匹配 a

三、实战场景:正则表达式的核心应用

3.1 场景 1:数据验证(最常用)

数据验证是正则表达式的经典场景,如验证手机号、邮箱、身份证号等,确保输入数据格式合法。

3.1.1 验证手机号(中国大陆)
  • 规则:11 位数字,以 13/14/15/17/18/19 开头
  • 正则表达式:^1[345789]\d{9}$

Java 实现

import java.util.regex.Pattern;

import java.util.regex.Matcher;

public class RegexDemo {

// 手机号正则表达式

private static final String PHONE_REGEX = "^1[345789]\\d{9}$";

private static final Pattern PHONE_PATTERN = Pattern.compile(PHONE_REGEX);

public static boolean validatePhone(String phone) {

if (phone == null || phone.isEmpty()) {

return false;

}

Matcher matcher = PHONE_PATTERN.matcher(phone);

return matcher.matches();

}

public static void main(String[] args) {

System.out.println(validatePhone("13812345678")); // true

System.out.println(validatePhone("12345678901")); // false(开头不是13/14等)

System.out.println(validatePhone("1381234567")); // false(不足11位)

}

}

Python 实现

import re

def validate_phone(phone):

phone_regex = r"^1[345789]\d{9}$"

return re.fullmatch(phone_regex, phone) is not None

# 测试

print(validate_phone("13812345678")) # True

print(validate_phone("12345678901")) # False

print(validate_phone("1381234567")) # False

3.1.2 验证邮箱
  • 规则:用户名 @域名(用户名可包含字母、数字、下划线、点号;域名至少包含一个点)
  • 正则表达式:^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$

Python 实现

def validate_email(email):

email_regex = r"^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$"

return re.fullmatch(email_regex, email) is not None

print(validate_email("test123@qq.com")) # True

print(validate_email("test.name_123@gmail.com")) # True

print(validate_email("test@.com")) # False(域名格式错误)

3.2 场景 2:字符串提取(从文本中提取目标信息)

从复杂文本中提取指定格式的信息(如提取日志中的 IP 地址、提取字符串中的数字)。

3.2.1 提取文本中的所有 IP 地址(IPv4)
  • IPv4 规则:4 组 0-255 的数字,以点号分隔(需处理 0-255 的范围限制)
  • 正则表达式:\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b

Java 实现

public class RegexExtract {

private static final String IP_REGEX = "\\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\b";

private static final Pattern IP_PATTERN = Pattern.compile(IP_REGEX);

public static List> extractIp(String text) {

List ips = new ArrayList

Matcher matcher = IP_PATTERN.matcher(text);

while (matcher.find()) { // 循环查找所有匹配的IP

ips.add(matcher.group());

}

return ips;

}

public static void main(String[] args) {

String log = "用户登录日志:IP=192.168.1.1,时间=2024-05-20;IP=255.255.255.255,时间=2024-05-21;无效IP=256.0.0.1";

ListIp(log);

System.out.println(ips); // 输出:[192.168.1.1, 255.255.255.255]

}

}

3.2.2 提取字符串中的所有数字(包括整数和小数)
  • 正则表达式:-?\d+(?:\.\d+)?(-?匹配负号,\d+匹配整数部分,(?:\.\d+)?匹配小数部分)

Python 实现

def extract_numbers(text):

number_regex = r"-?\d+(?:\.\d+)?"

return re.findall(number_regex, text)

text = "商品价格:99元,折扣价:89.9元,库存:-10(缺货),折扣率:0.85"

numbers = extract_numbers(text)

print(numbers) # 输出:['99', '89.9', '-10', '0.85']

3.3 场景 3:字符串替换(批量修改文本)

批量替换文本中的指定内容(如替换特殊字符、格式化日期、脱敏手机号)。

3.3.1 手机号脱敏(中间 4 位替换为 *)
  • 需求:将手机号13812345678替换为138****5678
  • 正则表达式:(\d{3})\d{4}(\d{4})(分组捕获前 3 位和后 4 位)

Java 实现

public class RegexReplace {

public static String maskPhone(String phone) {

String phoneRegex = "(\\d{3})\\d{4}(\\d{4})";

// 替换为:$1****$2($1表示第一个分组,$2表示第二个分组)

return phone.replaceAll(phoneRegex, "$1****$2");

}

public static void main(String[] args) {

System.out.println(maskPhone("13812345678")); // 输出:138****5678

}

}

3.3.2 清除文本中的所有空白字符
  • 正则表达式:\s+(匹配一个或多个空白字符)

Python 实现

def remove_whitespace(text):

return re.sub(r"\s+", "", text)

text = " 正则表达式 实战 指南 \n 2024-05-20 "

result = remove_whitespace(text)

print(result) # 输出:正则表达式实战指南2024-05-20

四、进阶技巧:提升正则表达式效率

4.1 分组与捕获
  • 捕获组:用()包裹的表达式会被捕获,可通过$n(Java)或\n(Python)引用捕获结果(如 3.3.1 中的手机号脱敏);
  • 非捕获组:用(?:)包裹的表达式仅用于分组,不捕获结果,可提升性能(如 IP 提取中的(?:25[0-5]...))。
4.2 贪婪匹配与非贪婪匹配
  • 贪婪匹配(默认):尽可能匹配更多字符(如a.*b匹配aabbaab中的aabbaab);
  • 非贪婪匹配:在量词后加?,尽可能匹配更少字符(如a.*?b匹配aabbaab中的aab和aab)。

示例(Python)

text = "aaabbbccc"

# 贪婪匹配:.* 匹配所有字符,直到最后一个c

greedy = re.findall(r"a.*c", text)

print(greedy) # 输出:['aaabbbccc']

# 非贪婪匹配:.*? 匹配到第一个c为止

non_greedy = re.findall(r"a.*?c", text)

print(non_greedy) # 输出:['aaabbbccc']?不,实际输出:['aaabbbccc']?不对,修正示例:

text = "aaacbbbc"

greedy = re.findall(r"a.*c", text) # 匹配整个字符串:['aaacbbbc']

non_greedy = re.findall(r"a.*?c", text) # 匹配到第一个c:['aaac']

4.3 正向预查与反向预查(零宽断言)

零宽断言仅匹配位置,不消耗字符,常用于 “匹配某个字符前后的内容”。

断言类型

语法

作用说明

示例

正向先行断言

(?=exp)

匹配 exp 前面的位置

a(?=b) 匹配ab中的a,不匹配ac中的a

正向负向断言

(?!exp)

匹配不满足 exp 前面的位置

a(?!b) 匹配ac中的a,不匹配ab中的a

反向先行断言

(?<=exp)

匹配 exp 后面的位置

(? 匹配ab中的b,不匹配cb中的b`

反向负向断言

(?<!exp)

匹配不满足 exp 后面的位置

(?b 匹配cb中的b,不匹配ab中的b

示例:匹配密码中包含至少 1 个大写字母、1 个小写字母和 1 个数字

  • 正则表达式:^(?=.*[A-Z])(?=.*[a-z])(?=.*\d).{8,16}$
  • 解析:
    • (?=.*[A-Z]):确保字符串中存在大写字母;
    • (?=.*[a-z]):确保存在小写字母;
    • (?=.*\d):确保存在数字;
    • .{8,16}:匹配 8-16 位任意字符。

五、避坑指南

  1. 转义字符问题:Java 中\需要双重转义(如\d需写为\\d),Python 中直接写\d即可;
  1. 性能问题:复杂正则表达式(如嵌套量词.*.*)可能导致回溯爆炸,尽量简化表达式(如用\d+代替\d*\d);
  1. 边界匹配:验证全字符串时务必加^和$(如手机号验证,否则138123456789会被误判为合法);
  1. 范围匹配:[0-9a-zA-Z]不能写成[a-z0-9A-Z](顺序不影响),但[a-Z]是错误的(大写字母 ASCII 码小于小写字母)。

六、常用工具推荐

  1. 在线正则表达式测试工具:Regex101(支持语法高亮、匹配结果实时预览,可选择语言);
  1. 正则表达式生成器:Regex Generator(输入示例文本,自动生成正则表达式);
  1. IDE 集成工具:IntelliJ IDEA、VS Code 均内置正则表达式测试功能(快捷键 Ctrl+F,开启 Regex 模式)。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/1 4:06:53

初识C语言(编译和链接)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录前言一、翻译环境和运⾏环境1. 翻译环境&#xff08;Translation Environment&#xff09;2. 运行环境&#xff08;Runtime Environment&#xff09;3. 环境差异示例…

作者头像 李华
网站建设 2026/5/1 4:04:56

java计算机毕业设计数据库加密系统 基于Java的敏感数据密文存储与访问控制系统 SpringBoot融合多算法的数据库透明加密平台

计算机毕业设计数据库加密系统ka8o09 &#xff08;配套有源码 程序 mysql数据库 论文&#xff09; 本套源码可以在文本联xi,先看具体系统功能演示视频领取&#xff0c;可分享源码参考。数据泄露事件年年上热搜&#xff0c;明文存储的身份证号、银行卡号一旦被“脱裤”就是一场灾…

作者头像 李华
网站建设 2026/5/1 4:05:11

探索三相异步电动机计算软件:哈理工电磁计算软件的魅力

三相异步电动机计算软件&#xff0c;哈理工电磁计算软件&#xff0c;支持鼠笼型电机&#xff0c;绕线型电机&#xff0c;双速电机。 ps:带部分案例库&#xff0c;可在案例库基础上新编辑;完全新建案例&#xff0c;输入项电机型号符号可复制案例库的符号编辑。在电机领域&#x…

作者头像 李华
网站建设 2026/4/30 7:12:12

Agent频繁失联怎么办,一文看懂云原生环境下的智能恢复机制

第一章&#xff1a;Agent频繁失联的根源剖析在分布式系统与自动化运维场景中&#xff0c;Agent作为核心数据采集与指令执行单元&#xff0c;其连接稳定性直接影响整体系统的可观测性与控制能力。当Agent出现频繁失联现象时&#xff0c;往往并非单一因素所致&#xff0c;而是多种…

作者头像 李华
网站建设 2026/5/1 9:00:32

如何在30分钟内构建高安全金融 Agent 验证链?:实战配置全流程

第一章&#xff1a;金融 Agent 安全验证的核心挑战在金融领域&#xff0c;Agent 系统&#xff08;如智能投顾、自动化交易机器人、风控代理等&#xff09;的广泛应用提升了服务效率与决策速度&#xff0c;但同时也引入了复杂的安全验证难题。这些系统通常需访问敏感数据、执行高…

作者头像 李华
网站建设 2026/5/1 8:42:53

实现异构Agent高效协作(基于语义对齐与协议协商的创新方案)

第一章&#xff1a;跨领域 Agent 的协同机制在分布式人工智能系统中&#xff0c;跨领域 Agent 协同机制是实现复杂任务分工与资源整合的核心。多个具备不同专业能力的 Agent 需要在异构环境中达成共识、共享状态并协调行为&#xff0c;以完成单一 Agent 无法独立解决的任务目标…

作者头像 李华