一、规则
在线测试页面
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 |
^ |
字符串开头 |
^a → apple |
$ |
字符串结尾 |
e$ → apple
|
| |
或运算符 |
(z|f)ood → zood, food
|
|
转义字符 |
. → a.b |
2. 分组与引用
| 语法 |
功能 |
示例 |
( ) |
捕获分组 |
(d{4}) → 2023-01 |
n |
引用第n个分组 |
^(abc)1$ → abcabc
|
(?) |
命名分组 |
(?d{4}) |
3. 字符集合简写
| 字符 |
等价于 |
含义 |
d |
[0-9] |
数字字符 |
w |
[A-Za-z0-9_] |
单词字符(字母、数字、下划线) |
s |
[ tnrfv] |
空白字符(空格、制表符等) |
b |
– |
单词边界 |
n |
– |
换行符 |
t |
– |
制表符 |
r |
– |
回车符 |
4. 反向字符类
| 字符 |
等价于 |
含义 |
D |
[^0-9] |
非数字字符 |
W |
[^A-Za-z0-9_] |
非单词字符 |
S |
[^ tnrfv] |
非空白字符 |
B |
– |
非单词边界 |
5. 特殊字符类
| 字符 |
含义 |
f |
换页符 |
v |
垂直制表符 |
|
空字符 |
cx |
控制字符(如 cM 匹配回车) |
xhh |
十六进制值 hh 表示的字符 |
uhhhh |
Unicode 字符 |
6. 零宽断言
| 语法 |
名称 |
示例 |
(?=...) |
正向先行断言 |
d+(?=px) → 12px, 15px
|
(?!...) |
负向先行断言 |
d{3}(?!px) → 123px, 456em
|
(? |
正向后行断言 |
(? → **$**100
|
(? |
负向后行断言 |
(? → 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|1d{2}|[1-9]?d).){3}(25[0-5]|2[0-4]d|1d{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标签 |
/^|>(.*?))$/ |
| 文件路径 |
/^(/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) |
分组 |
匹配完整的 z 或 f
|
(z|f)ood → zood, food
|
[z|f] |
字符集 |
匹配单个字符 z、f 或 |
|
[z|f] → z, f, |
|
-
(z|f) 是选择模式,匹配整个 z 或 f
-
[z|f] 是字符集合,匹配方括号内的任意单个字符(包括字面量 |)
[z|f]ood # 会意外匹配 "|ood"
(z|f)ood # 正确匹配 "zood" 或 "food" 或 “|ood”
2. 断言与捕获的区别
| 语法 |
名称 |
特点 |
示例 |
(?=...) |
正向先行断言 |
不消耗字符,只检查右侧 |
d+(?=px) → 匹配”12″(在”12px”中) |
(?!...) |
负向先行断言 |
不包含在匹配结果中 |
d{3}(?!px) → 匹配”456″(当后面不是”px”时) |
(? |
正向后行断言 |
检查左侧但不捕获 |
(? → 匹配"100"(当前面是$时)
|
(? |
负向后行断言 |
不消耗左侧字符 |
(? → 匹配"200"(当前面不是$时)
|
| 语法 |
特点 |
示例 |
(...) |
消耗字符并存储匹配内容 |
(d{4})-(d{2}) → 捕获”2023″和”01″(从”2023-01″中) |
(?:...) |
不捕获的纯分组 |
(?:d{3})-(d{4}) → 只捕获后4位数字 |
-
核心区别
-
内存消耗
- 断言:不占用匹配结果(零宽度)
- 捕获:会存储匹配内容
-
应用场景
// 断言(提取价格数字但不包含货币符号)
"Price: $100".match(/(?
2. 断言怎么用
正向先行断言 (?=…)
- 示例:匹配后面跟着句号的数字
d(?=.)
示例文本:1. 5. 7
匹配结果(两个):(1, 5)
负向先行断言 (?!..)
- 示例:匹配后面不跟着句号的数字
d(?!.)
示例文本:1. 5 7
匹配结果(两个):(5, 7)
正向后行断言 (?
- 示例:匹配前面是字母的数字
(?
示例文本:a1 b2 3c
匹配结果(两个):(1, 2)
负向后行断言 (?
- 示例:匹配前面不是字母的数字
(?
示例文本:1a2b 3
匹配结果(两个):(1, 3)
单词边界 (b)
- 示例:匹配独立的单词”cat”
bcatb
示例文本:cat category a cat
匹配结果(两个):(cat, cat)
行首/行尾 (^ 和 $)
- 示例:匹配以 “Hello” 开头的行
^Hello
示例文本:Hello world Hello there
匹配结果:Hello
三、实际操作
1. vscode 正则替换
- 所有注释加一个空格
//heeeeellll ---> // heeeeellll
#heeeeellll ---> # heeeeellll
(?
- function 转 const
#查找:functions(w+)((.*))
#替换:const $1 = ($2) =>
结果:
function screenCheck()
const screenCheck = () =>
- as
查找:([w|.]+)
替换:$2 as $1
结果:
controller as FunctionController
controller
2. c++用法
1. regex_match 整个字符串 要求完全匹配!
std::cmatch m;
auto ret = std::regex_match("value", m, std::regex("(.*)"));
if (ret)
{
std::cout value
16
0
valuevalue
xml xml
value value
xml xml
-------------------------------
2. regex_search 只要字符串中有目标出现就会返回,而非完全「匹配」
std::cmatch m;
auto ret = std::regex_match("123value456", m, std::regex("(.*)"));
if (ret)
{
for (auto& elem : m)
std::cout value
xml
value
xml
prefix:123
suffix:456
-------------------------------
// 注意:如果有多个符合的内容
std::regex reg("(.*)(.*)>");
std::string content("123value456centerhahahawindowthe 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 value
xml
value
xml
----------------
center
widget
center
widget
----------------
window
vertical
window
vertical
-------------------------------
3. regex_replace 在整个字符串中替换符合正则表达式规则的字段
string str = "Hello_2018!";
regex pattern("Hello");
cout
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 = "标题
正文内容
"
tags = re.findall(r'(.*?)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|1d{2}|[1-9]?d).){3}(25[0-5]|2[0-4]d|1d{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'bw{4}b') # 匹配4字母单词
text = "This is sample text with some four letter words"
matches = pattern.findall(text)
print("🔤 4字母单词:", matches)
总结
到此这篇关于正则表达式常见困惑与实际操作的文章就介绍到这了,更多相关正则表达式速查指南内容请搜索IT俱乐部以前的文章或继续浏览下面的相关文章希望大家以后多多支持IT俱乐部!