news 2026/6/12 3:34:47

关于正则表达式

作者头像

张小明

前端开发工程师

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/6/10 13:35:41

实时异常检测是如何实现的?工业Agent数据分析中的5个核心算法揭秘

第一章&#xff1a;实时异常检测是如何实现的&#xff1f;工业Agent数据分析中的5个核心算法揭秘在现代工业物联网&#xff08;IIoT&#xff09;系统中&#xff0c;实时异常检测是保障生产连续性与设备健康的关键能力。通过部署在边缘设备或云端的智能Agent&#xff0c;系统能够…

作者头像 李华
网站建设 2026/6/9 18:38:09

学生轻薄本电脑推荐/哪家好:适合学生使用的轻薄型笔记本电脑全面解析

在当今数字化学习环境中&#xff0c;一款适合学生使用的轻薄型笔记本电脑已成为不可或缺的学习工具。面对市场上琳琅满目的产品&#xff0c;如何选择一款真正适合自己的轻薄本&#xff1f;本文将为您提供客观、实用的选购指南&#xff0c;帮助您找到最适合的轻薄本。选择学生轻…

作者头像 李华
网站建设 2026/6/12 2:35:12

2025各大品牌学生游戏本电脑推荐及其散热性能对比

引言随着2025年游戏产业的蓬勃发展&#xff0c;高性能游戏本已成为学生群体的刚需装备。在兼顾学习、娱乐与创作的多重需求下&#xff0c;散热性能成为影响用户体验的关键指标。本文基于2025年12月的市场数据与实际测试&#xff0c;对主流品牌学生游戏本进行客观推荐与散热性能…

作者头像 李华
网站建设 2026/6/9 19:47:43

【资深工程师亲授】:构建懂交规的自动驾驶Agent的5个关键步骤

第一章&#xff1a;自动驾驶Agent与交通规则的融合挑战自动驾驶技术的发展正推动交通系统向智能化演进&#xff0c;然而将自动驾驶Agent&#xff08;Autonomous Agent&#xff09;与现实世界复杂的交通规则体系深度融合&#xff0c;仍面临多重挑战。交通规则不仅是静态的法规条…

作者头像 李华
网站建设 2026/6/10 18:14:00

为什么90%的农场主都用错了施肥算法?揭秘农业Agent背后的科学逻辑

第一章&#xff1a;农业种植 Agent 的施肥量在现代农业智能化系统中&#xff0c;农业种植 Agent 通过感知环境数据与作物生长状态&#xff0c;动态决策最优施肥量。该过程融合土壤养分检测、气象信息及作物需肥规律&#xff0c;实现精准农业管理。施肥决策的数据输入 Agent 的施…

作者头像 李华
网站建设 2026/6/10 12:23:35

DevOps:开发运维一体化的未来之路

一、DevOps概念基本概念在如今互联网的格局下&#xff0c;抢占市场变得尤为重要&#xff0c;因此**敏捷开发**越来越被大家所推崇。于是&#xff0c;慢慢的有了DevOps这个概念&#xff0c;含义就是**开发-运维一体化**&#xff0c;能够理顺开发和运维之间相互配合关系的任何事物…

作者头像 李华