正则表达式常见困惑与实际操作(速查指南)

 更新时间:2026年08月29日 10:10:23   作者:DIY全栈开发  
正则表达式通常被用来检索或者替换那些符合某个模式的文本内容,根据指定的匹配模式匹配文本中符合要求的特殊的字符串,这篇文章主要介绍了正则表达式常见困惑与实际操作的相关资料,需要的朋友可以参考下

一、规则

在线测试页面

1. 基础元字符

字符含义示例
.匹配除换行符外任意字符a.c → abc
[]字符集合[ae]apple, egg
[^]否定字符集[^ae] → apple, egg
*匹配0次或多次zo*z, zo, zoo
+匹配1次或多次zo+ → z, zo, zoo
?匹配0次或1次zo?z, zo, zoo
{n}匹配n次o{2} → food
{n,}至少匹配n次o{2,} → foood
{n,m}匹配n到m次o{2,3} → foood
^字符串开头^aapple
$字符串结尾e$ → apple
|或运算符(z|f)oodzood, food
\转义字符\. → a.b

2. 分组与引用

语法功能示例
( )捕获分组(\d{4})2023-01
\n引用第n个分组^(abc)\1$abcabc
(?<name>)命名分组(?<year>\d{4})

3. 字符集合简写

字符等价于含义
\d[0-9]数字字符
\w[A-Za-z0-9_]单词字符(字母、数字、下划线)
\s[ \t\n\r\f\v]空白字符(空格、制表符等)
\b-单词边界
\n-换行符
\t-制表符
\r-回车符

4. 反向字符类

字符等价于含义
\D[^0-9]非数字字符
\W[^A-Za-z0-9_]非单词字符
\S[^ \t\n\r\f\v]非空白字符
\B-非单词边界

5. 特殊字符类

字符含义
\f换页符
\v垂直制表符
\0空字符
\cx控制字符(如 \cM 匹配回车)
\xhh十六进制值 hh 表示的字符
\uhhhhUnicode 字符

6. 零宽断言

语法名称示例
(?=...)正向先行断言\d+(?=px) → 12px, 15px
(?!...)负向先行断言\d{3}(?!px) → 123px, 456em
(?<=...)正向后行断言(?<=\$)\d+ → **$**100
(?<!...)负向后行断言(?<!\$)\d+ → 100, €200

7. 标志符

标志功能
g全局搜索
i不区分大小写
m多行模式

8. 常用正则模式

用途正则表达式
用户名/^[a-z0-9_-]{3,16}$/
电子邮箱/^[\w\.-]+@[\w\.-]+\.[a-z]{2,6}$/
URL/^(https?:\/\/)?[\w\.-]+\.[a-z]{2,6}\/?[\w\/\.-]*$/
IPv4地址/((25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)\.){3}(25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)/
日期/^(0?[1-9]|1[0-2])[\/\-\.](0?[1-9]|[12]\d|3[01])[\/\-\.]\d{4}$/
中文姓名/^[\u4e00-\u9fa5]{2,4}$/
手机号码/^1[3-9]\d{9}$/
身份证号/^[1-9]\d{5}(18|19|20)\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])\d{3}[\dX]$/
信用卡号/^\d{4}[- ]?\d{4}[- ]?\d{4}[- ]?\d{4}$/
十六进制颜色值/^#?([a-f0-9]{6}|[a-f0-9]{3})$/i
HTML标签/^<([a-z]+)([^<]+)*(?:\/>|>(.*?)<\/\1>)$/
文件路径/^(\/\w+)+\/?(\w+\.\w+)?$/
金额(两位小数)/^\d+(\.\d{1,2})?$/
MAC地址/^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$/
车牌号(中国)/^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼][A-Z][A-Z0-9]{5}$/

二、常见困惑

1.(z|f)和[z|f]的区别

表达式类型匹配内容示例匹配结果
(z|f)分组匹配完整的 zf(z|f)oodzood, food
[z|f]字符集匹配单个字符 zf|[z|f]z, f, |
  • 关键区别:
  1. (z|f)选择模式,匹配整个 zf
  2. [z|f]字符集合,匹配方括号内的任意单个字符(包括字面量 |
  • 常见错误示例:
[z|f]ood  # 会意外匹配 "|ood"
(z|f)ood   # 正确匹配 "zood" 或 "food" 或 “|ood”

2. 断言与捕获的区别

  • 断言(零宽断言)
语法名称特点示例
(?=...)正向先行断言不消耗字符,只检查右侧\d+(?=px) → 匹配"12"(在"12px"中)
(?!...)负向先行断言不包含在匹配结果中\d{3}(?!px) → 匹配"456"(当后面不是"px"时)
(?<=...)正向后行断言检查左侧但不捕获(?<=\$)\d+ → 匹配"100"(当前面是$时)
(?<!...)负向后行断言不消耗左侧字符(?<!\$)\d+ → 匹配"200"(当前面不是$时)
  • 捕获组
语法特点示例
(...)消耗字符并存储匹配内容(\d{4})-(\d{2}) → 捕获"2023"和"01"(从"2023-01"中)
(?:...)不捕获的纯分组(?:\d{3})-(\d{4}) → 只捕获后4位数字
  • 核心区别

    1. 内存消耗

      • 断言:不占用匹配结果(零宽度)
      • 捕获:会存储匹配内容
    2. 应用场景

	   // 断言(提取价格数字但不包含货币符号)
	   "Price: $100".match(/(?<=\$)\d+/); // → ["100"]
	   
	   // 捕获(同时获取货币符号和数字)
	   "Price: $100".match(/(\$)(\d+)/);  // → ["$100", "$", "100"]
		[0]	"$100"	完整匹配的字符串
		[1]	"$"	第一个捕获组 (\$) 匹配的内容
		[2]	"100"	第二个捕获组 (\d+) 匹配的内容

2. 断言怎么用

正向先行断言 (?=…)

  • 示例:匹配后面跟着句号的数字
    \d(?=.)
    示例文本:1. 5. 7
    匹配结果(两个):(1, 5)

负向先行断言 (?!..)

  • 示例:匹配后面不跟着句号的数字
    \d(?!\.)
    示例文本:1. 5 7
    匹配结果(两个):(5, 7)

正向后行断言 (?<=…)

  • 示例:匹配前面是字母的数字
    (?<=[a-zA-Z])\d
    示例文本:a1 b2 3c
    匹配结果(两个):(1, 2)

负向后行断言 (?<!..)

  • 示例:匹配前面不是字母的数字
    (?<![a-zA-Z])\d
    示例文本:1a2b 3
    匹配结果(两个):(1, 3)

单词边界 (b)

  • 示例:匹配独立的单词"cat"
    \bcat\b
    示例文本:cat category a cat
    匹配结果(两个):(cat, cat)

行首/行尾 (^ 和 $)

  • 示例:匹配以 “Hello” 开头的行
    ^Hello
    示例文本:Hello world Hello there
    匹配结果:Hello

三、实际操作

1. vscode 正则替换

  1. 所有注释加一个空格
//heeeeellll ---> // heeeeellll
#heeeeellll ---> # heeeeellll  
(?<!:)(//)(\S.*|[\u4E00-\u9FFF].*)
(#)(\S.*|[\u4E00-\u9FFF].*)
$1 $2
  1. function 转 const
#查找:function\s(\w+)\((.*)\)
#替换:const $1 = ($2)  => 

结果:
function screenCheck()
const screenCheck = ()  =>
  1. as
查找:<([\w|.]+)>([\w|.]+)
替换:$2 as $1

结果:
controller as FunctionController
<FunctionController>controller

2. c++用法

1. regex_match 整个字符串 要求完全匹配!

std::cmatch m;
auto ret = std::regex_match("<xml>value</xml>", m, std::regex("<(.*)>(.*)</xml>"));
if (ret)
{
	std::cout << m.str() << std::endl;
	std::cout << m.length() << std::endl;
	std::cout << m.position() << std::endl;
}

// 遍历匹配内容
for (auto i = 0; i < m.size(); ++i)
{
	// 两种方式都可以 输出括号()捕获的子串
	std::cout << m[i].str() << " " << m.str(i) << std::endl;
}

-------------------------------
<xml>value</xml>
16
0

<xml>value</xml> <xml>value</xml>
xml xml
value value
xml xml
-------------------------------

2. regex_search 只要字符串中有目标出现就会返回,而非完全「匹配」

std::cmatch m;
auto ret = std::regex_match("123<xml>value</xml>456", m, std::regex("<(.*)>(.*)</xml>"));
if (ret)
{
	for (auto& elem : m)
		std::cout << elem << std::endl;
}
std::cout << "prefix:" << m.prefix() << std::endl;
std::cout << "suffix:" << m.suffix() << std::endl;

-------------------------------
<xml>value</xml>
xml
value
xml

prefix:123
suffix:456
-------------------------------

// 注意:如果有多个符合的内容
std::regex reg("<(.*)>(.*)</(.*)>");
std::string content("123<xml>value</xml>456<widget>center</widget>hahaha<vertical>window</vertical>the end");
std::smatch m;
auto pos = content.cbegin();
auto end = content.cend();
for (; std::regex_search(pos, end, m, reg); pos = m.suffix().first)
{
	std::cout << "----------------" << std::endl;
	std::cout << m.str() << std::endl;
	std::cout << m.str(1) << std::endl;
	std::cout << m.str(2) << std::endl;
	std::cout << m.str(3) << std::endl;
}

-------------------------------
<xml>value</xml>
xml
value
xml
----------------
<widget>center</widget>
widget
center
widget
----------------
<vertical>window</vertical>
vertical
window
vertical
-------------------------------

3. regex_replace 在整个字符串中替换符合正则表达式规则的字段

string str = "Hello_2018!";	

regex pattern("Hello");	
cout << regex_replace(str, pattern, "") << endl;	//输出:_2018,将Hello替换为""
cout << regex_replace(str, pattern, "Hi") << endl;	//输出:Hi_2018,将Hello替换为Hi

regex pattern2("(.{3})(.{2})_(\\d{4})");				//匹配3个任意字符+2个任意字符+下划线+4个数字
cout << regex_replace(str, pattern2, "$1$3") << endl;	//输出:Hel2018,将字符串替换为第一个和第三个表达式匹配的内容
cout << regex_replace(str, pattern2, "$1$3$2") << endl;	//输出:Hel2018lo,交换位置顺序

3. js 用法

var str = "aaabbbcccaaabbbccc";

// match
var res = str.match(/aaa/); // 没有使用g选项
输出:[ 'aaa', index: 0, input: 'aaabbbcccaaabbbccc' ]

var res = str.match(/aaa/g); // g(全局匹配) 使用g选项,全局匹配
输出:[ 'aaa', 'aaa' ]

// exec
var res =/aaa/.exec(str);
输出:[ 'aaa', index: 0, input: 'aaabbbcccaaabbbccc' ]

var res =/aaa/g.exec(str);
输出:[ 'aaa', index: 0, input: 'aaabbbcccaaabbbccc' ]

var res = /ccc([0-9]+)aaa/.exec("aaabbbccc1234aaabbbcccaaabbbccc5678aaabbbccc");
输出:[ 'ccc1234aaa', '1234', index: 6, input: 'aaabbbccc1234aaabbbccc' ]

var res = /ccc([0-9]+)aaa/g.exec("aaabbbccc1234aaabbbcccaaabbbccc5678aaabbbccc");
"ttt.md".match(/(.*).md/)[1]; //返回匹配数组

输出:[ 'ccc1234aaa', '1234', index: 6, input: 'aaabbbccc1234aaabbbcccaaabbbccc5678aaabbbccc' ][ 'ccc5678aaa', '5678', index: 28, input: 'aaabbbccc1234aaabbbcccaaabbbccc5678aaabbbccc' ]

/.*\.md$/g.exec("ttt.md")[1]; //返回匹配数组

// search
var res = "aaabbbcccaaabbbccc".search(/ccc/)
输出: 6

var res = "aaabbbcccaaabbbccc".replace(/aaa/, '111′);
输出: 111bbbcccaaabbbccc

// split
var res = "aaa,bbb,ccc".split(/,/)
输出: [ 'aaa', 'bbb', 'ccc' ]
var res = "aaa,bbb:ccc@ddd#eee".split(/[,:@#]/)
输出: [ 'aaa', 'bbb', 'ccc', 'ddd', 'eee' ]
var res = "aaa,bbb:ccc@ddd#eee".split(/[,:@#]/,3)
输出: [ 'aaa', 'bbb', 'ccc' ]

4. python 用法

import re

# 1. 邮箱验证
emails = ["test@example.com", "invalid@.com", "name@domain.org"]
pattern = r'^[\w\.-]+@[\w\.-]+\.[a-zA-Z]{2,6}$'
for email in emails:
    if re.match(pattern, email):
        print(f"✅ 有效邮箱: {email}")
    else:
        print(f"❌ 无效邮箱: {email}")

# 2. 提取日期信息
text = "会议时间: 2023-08-15, 截止日期: 2024-01-20"
dates = re.findall(r'(\d{4})-(\d{2})-(\d{2})', text)
for year, month, day in dates:
    print(f"📅 日期: {year}年{month}月{day}日")

# 3. 替换敏感词
content = "这个价格是500元,但VIP价格是400元"
sanitized = re.sub(r'VIP价格', '***', content)
print(f"🔒 脱敏内容: {sanitized}")

# 4. 分割复杂字符串
data = "Alice:30;Bob:25;Charlie:28"
users = re.split(r'[;:]', data)
print("👥 用户数据:", users)

# 5. 提取HTML标签内容
html = "<div>标题</div><p>正文内容</p>"
tags = re.findall(r'<([a-z]+)>(.*?)</\1>', html)
for tag, content in tags:
    print(f"🏷️ {tag}标签内容: {content}")

# 6. 密码强度验证
passwords = ["Pass123!", "weak", "StrongPwd#2023"]
for pwd in passwords:
    if re.match(r'^(?=.*[A-Z])(?=.*[a-z])(?=.*\d)(?=.*[!@#$%^&*]).{8,}$', pwd):
        print(f"🔐 强密码: {pwd}")
    else:
        print(f"⚠️ 弱密码: {pwd}")

# 7. 提取中文内容
text = "Python3.8发布 2020年10月,支持中文变量名=很棒"
chinese = re.findall(r'[\u4e00-\u9fa5]+', text)
print("🇨🇳 中文内容:", chinese)

# 8. 匹配IP地址
ips = ["192.168.1.1", "256.0.0.1", "127.0.0.1"]
pattern = r'^((25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)\.){3}(25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)$'
for ip in ips:
    if re.match(pattern, ip):
        print(f"🌐 有效IP: {ip}")
    else:
        print(f"🚫 无效IP: {ip}")

# 9. 多行模式匹配
text = """标题
第一行
最后一行"""
match = re.search(r'^最后一行$', text, re.MULTILINE)
if match:
    print(f"📝 找到结尾行: '{match.group()}'")

# 10. 预编译正则提高性能
pattern = re.compile(r'\b\w{4}\b')  # 匹配4字母单词
text = "This is sample text with some four letter words"
matches = pattern.findall(text)
print("🔤 4字母单词:", matches)

总结 

到此这篇关于正则表达式常见困惑与实际操作的文章就介绍到这了,更多相关正则表达式速查指南内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 十分钟上手正则表达式 上篇

    十分钟上手正则表达式 上篇

    正则表达式(regular expression)描述了一种字符串匹配的模式(pattern),可以用来检查一个串是否含有某种子串、将匹配的子串替换或者从某个串中取出符合某个条件的子串等
    2021-10-10
  • 正则表达式实现字符串每4位后自动加空格效果(两种方法)

    正则表达式实现字符串每4位后自动加空格效果(两种方法)

    本文通过两种方法给大家介绍了正则表达式实现字符串每4位后自动加空格效果,需要的朋友可以参考下
    2018-09-09
  • 正则表达式模式修正符(/ies)

    正则表达式模式修正符(/ies)

    下面列出了当前在 PCRE 中可能使用的修正符。括号中是这些修正符的内部 PCRE 名。修正符中的空格和换行被忽略,其它字符会导致错误。
    2010-08-08
  • 正则表达式 匹配至少有一个非空白字符并且不超过指定长度

    正则表达式 匹配至少有一个非空白字符并且不超过指定长度

    最近需要用到一个验证,规则为:至少有一个非空白字符并且不超过指定长度,想用正则表达式来处理,上网搜了一下,发现其他人也有和我一样的需求,并且有高手给了几个很精彩的解决方案,现将网上的解决方案整理一下,以备其他有相同需求的人参考
    2011-11-11
  • javascript下一个还原html代码的正则

    javascript下一个还原html代码的正则

    javascript下一个还原html代码的正则...
    2007-08-08
  • Hive中常用正则表达式的运用小结

    Hive中常用正则表达式的运用小结

    在实际的应用中,通常需要在一些复杂的、没有规律的字符串中提取数据,这时候就需要用到正则表达式了,这次讲一下hive的正则表达式,感兴趣的朋友跟随小编一起看看吧
    2022-08-08
  • re模块的正则匹配的表达式详解

    re模块的正则匹配的表达式详解

    这篇文章主要介绍了使用的re模块的正则匹配的表达式,本文给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2019-07-07
  • JavaScript 正则表达式(笔记)

    JavaScript 正则表达式(笔记)

    这篇文章主要介绍了JavaScript 正则表达式(笔记) ,这里总结了js中的一些正则的使用方法,需要的朋友可以参考下
    2015-04-04
  • 前端基础知识之正则表达式用法

    前端基础知识之正则表达式用法

    正则表达式是一种强大的文本处理工具,它使用一种专门的语法来描述字符序列的模式 (pattern),通过这些模式,您可以在文本中进行复杂的搜索、替换、提取和验证操作,这篇文章主要介绍了前端基础知识之正则表达式用法的相关资料,需要的朋友可以参考下
    2026-08-08
  • 匹配yyyy-mm-dd日期格式的的正则表达式

    匹配yyyy-mm-dd日期格式的的正则表达式

    今天头让我修改个javascript方法,验证输入的日期是否符合要求。恩。我们的要求是yyyy-mm-dd这样的格式,其他的统统不符合要求。原来的方法没用正则表达式,用了一堆判断。
    2011-08-08

最新评论