news 2026/3/25 4:33:05

关于正则表达式

作者头像

张小明

前端开发工程师

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/3/22 3:02:24

自动驾驶环境感知系统如何实现99.99%识别准确率?深度解析AI感知算法演进路径

第一章&#xff1a;自动驾驶环境感知系统概述 自动驾驶环境感知系统是实现车辆自主决策与安全行驶的核心基础&#xff0c;其目标是通过多种传感器实时、准确地获取车辆周围环境信息&#xff0c;并对行人、车辆、交通标志、道路边界等关键要素进行识别与跟踪。该系统如同自动驾驶…

作者头像 李华
网站建设 2026/3/22 6:25:17

元宇宙从概念到落地:破解规模化沉浸体验的五大核心挑战

元宇宙已不再是科幻小说中的遥远构想&#xff0c;它正在迅速渗透至企业培训、产品展示、数字孪生、虚拟协作等核心商业场景。然而&#xff0c;许多企业在拥抱这一趋势时发现&#xff0c;从构建一个演示原型到部署一个稳定、可规模化使用的沉浸式环境&#xff0c;中间横亘着巨大…

作者头像 李华
网站建设 2026/3/18 22:37:24

Comsol 助力光子晶体光纤光学仿真:从论文复现到模式分析

comsol光学仿真 光子晶体光纤 论文复现&#xff08;图是仿的一个spr传感器和一个三芯分束器&#xff09;图左原文&#xff0c;图右仿的结果 基于SPR的光纤传感器 光子晶体光纤偏振分束器 光子晶体光纤仿真 模式分析 计算等效折射率&#xff0c;限制损耗&#xff0c;模式色散&am…

作者头像 李华
网站建设 2026/3/24 15:55:52

从田间到云端:农业物联网Agent通信协议选型终极指南

第一章&#xff1a;农业物联网Agent通信协议概述在现代农业系统中&#xff0c;物联网&#xff08;IoT&#xff09;技术正逐步实现农田环境监测、智能灌溉与自动化养殖等关键功能。其核心在于各类感知设备&#xff08;如土壤湿度传感器、气象站&#xff09;与控制单元&#xff0…

作者头像 李华
网站建设 2026/3/23 10:40:36

揭秘金融系统审计盲区:如何通过Agent日志提前发现合规风险?

第一章&#xff1a;金融合规 Agent 的审计日志在金融行业&#xff0c;系统操作的可追溯性与安全性至关重要。审计日志作为合规性保障的核心组件&#xff0c;能够记录所有关键操作行为&#xff0c;确保在监管审查或安全事件中提供完整的行为链证据。金融合规 Agent 通过自动化机…

作者头像 李华