正则表达式入门与实例:用JavaScript搞定文本校验
你一定见过这种场景:用户在注册表单里填了个 abc@def,你想拦却拦不住;后端传来一串手机号,你肉眼看不出是不是多了个空格;领导让你从一段日志里提取所有 IP 地址,你只能一行行复制粘贴。这些问题,正则表达式(Regular Expression,简称 regex)一个模式就能解决。
正则表达式是程序员的文本瑞士军刀。无论是表单验证、日志分析、数据清洗还是 URL 路由匹配,它都是首选工具。本文用 JavaScript(ES6+) 做示例,覆盖从语法基础到实战避坑,帮助你真正上手。
一、正则能解决什么问题?
先把痛点说清楚。正则表达式的核心能力就三个:
- 匹配(Test):这段文本是否符合某个模式?如验证邮箱格式。
- 提取(Match):从文本中捞出符合条件的片段。如从日志提取 IP 地址。
- 替换(Replace):把符合模式的内容替换成别的。如敏感词脱敏。
没有正则的时候,你可能要写一堆 String.indexOf + substring 的拼接代码,复杂且难维护。用正则,一行搞定。
二、JavaScript 中创建正则的两种方式
JavaScript 中有两种创建正则的方式,各有适用场景:
1. 字面量语法(推荐)
const re = /pattern/flags;
适用于pattern在写代码时就确定的情况。性能更好(引擎在编译期就解析好了)。
2. 构造函数(动态构建)
const re = new RegExp('pattern', 'flags');
适用于pattern需要动态拼接的情况,比如根据变量组装正则。
const fieldName = 'email';
const re = new RegExp(`^${fieldName}:\\s*(.+)
正则表达式入门与实例完全指南
正则表达式
正则表达式入门实例
← 返回工具首页
, 'm');
// 匹配 "email: test@example.com"
Flags(标志位)一览
Flag 含义 说明
g全局匹配 找出所有匹配,不只是第一个
i忽略大小写 A 匹配 a
m多行模式 ^ 和 $ 匹配每行开头/结尾
s单行模式 . 匹配换行符
uUnicode 模式 正确处理 Unicode 字符
三、基础语法:元字符速查
字符类
[abc] // 匹配 a、b 或 c 中的任意一个
[^abc] // 匹配除了 a、b、c 以外的任意字符
[a-z] // 匹配小写字母
[A-Z] // 匹配大写字母
[0-9] // 匹配数字,等价于 \d
预定义字符类
\d // 数字 [0-9]
\D // 非数字 [^0-9]
\w // 单词字符 [A-Za-z0-9_]
\W // 非单词字符
\s // 空白字符(空格、制表符、换行等)
\S // 非空白字符
. // 任意字符(换行符除外,s模式下包含换行)
锚点(Assertion)
^ // 字符串开头(多行模式下为行开头)
$ // 字符串结尾(多行模式下为行结尾)
\b // 单词边界
\B // 非单词边界
注意:^ 在字符类 [] 内部时是"取反"的意思,在外部是"开头锚点"。这是很多人容易搞混的地方。
量词(Quantifier)
{n} // 恰好 n 次
{n,} // 至少 n 次
{n,m} // n 到 m 次
* // 0次或多次,等价于 {0,}
+ // 1次或多次,等价于 {1,}
? // 0次或1次,也用于非贪婪模式
量词默认是贪婪的,会尽可能多匹配。加上 ? 变成非贪婪(lazy)模式:
'1234'.match(/\d+/g) // ["1234"] 贪婪:全拿
'1234'.match(/\d+?/g) // ["1","2","3","4"] 非贪婪:够用就行
分组与引用
(abc) // 捕获组,匹配并记住
(?:abc) // 非捕获组,匹配但不记住(性能更好)
(?<name>abc) // 命名捕获组(ES2018+)
// 引用分组
'2026-05-08'.replace(/(\d{4})-(\d{2})-(\d{2})/, '$2/$3/$1')
// 结果: "05/08/2026"
或运算
cat|dog // 匹配 "cat" 或 "dog"
四、实战示例:用 JavaScript 验证常见数据
示例1:验证邮箱格式
邮箱格式看似简单,但完整的 RFC 5322 规范极其复杂。实际开发中通常用简化版即可:
function isValidEmail(email) {
const re = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
return re.test(email);
}
console.log(isValidEmail('test@example.com')); // true
console.log(isValidEmail('invalid-email')); // false
console.log(isValidEmail('@example.com')); // false
解释:
^ 和 $ 确保从头到尾整个字符串符合格式,防止 abc@test.com.abc 这样的非法邮箱通过。
[a-zA-Z0-9._%+-]+ 匹配本地部分(@前面的部分),允许字母、数字和常见符号。
@[a-zA-Z0-9.-]+ 匹配域名。
\.[a-zA-Z]{2,} 匹配顶域(如 .com、.cn),至少2个字母。
示例2:验证中国手机号(11位)
function isValidPhone(phone) {
// 严格:1开头,第二位是3-9,后面9位数字
const re = /^1[3-9]\d{9}$/;
return re.test(phone);
}
console.log(isValidPhone('13812345678')); // true
console.log(isValidPhone('1381234567')); // false(10位)
console.log(isValidPhone('23812345678')); // false(非1开头)
console.log(isValidPhone('138123456789')); // false(12位)
console.log(isValidPhone('138 1234 5678')); // false(含空格)
如果需要兼容空格或横杠分隔的格式:
function isValidPhoneFlexible(phone) {
const re = /^1[3-9][\s-]?\d{4}[\s-]?\d{4}$/;
return re.test(phone.replace(/\s/g, '')); // 先去掉空格再验证
}
示例3:提取 URL 中的域名和路径
const url = 'https://clovertools.cn/tools/code/regex-tester.html?from=article';
// 捕获组:协议、域名、路径、查询参数
const re = /^([https]+):\/\/([^\/]+)(\/[^?]*)?(\?.*)?$/;
const match = url.match(re);
if (match) {
console.log('协议:', match[1]); // https
console.log('域名:', match[2]); // tools.xsanye.cn
console.log('路径:', match[3]); // /tools/code/regex-tester.html
console.log('查询:', match[4]); // ?from=article
}
// 用命名捕获组(更清晰)
const reNamed = /^(?<protocol>https?):\/\/(?<host>[^\/]+)(?<path>\/[^\?]*)?(?<query>\?.*)?$/;
const named = url.match(reNamed);
console.log(named.groups?.host); // tools.xsanye.cn
示例4:提取日志中的 IP 地址
const log = `2026-05-08 10:23:45 请求来自 192.168.1.100,处理完成
2026-05-08 10:24:11 请求来自 10.0.0.255,异常: 超时
2026-05-08 10:25:33 请求来自 192.168.1.100,限流触发`;
// 提取所有 IP(简化版,符合 IPv4)
const ipRe = /\b(\d{1,3}\.){3}\d{1,3}\b/g;
const ips = log.match(ipRe);
console.log([...new Set(ips)]);
// ["192.168.1.100", "10.0.0.255"]
// 用 Set 去重
示例5:敏感信息脱敏(手机号、身份证)
function maskPhone(phone) {
return phone.replace(/(\d{3})\d{4}(\d{4})/, '$1****$2');
}
function maskId(id) {
return id.replace(/(\d{6})\d{8}(\w{4})/, '$1********$2');
}
console.log(maskPhone('13812345678')); // 138****5678
console.log(maskId('110101199001011234')); // 110101********1234
五、常见错误与排坑指南
错误1:忘记 ^ 和 $ 锚点,匹配到部分内容
// 错误写法:验证是否包含邮箱
const re = /[a-z]+@[a-z]+\.[a-z]+/;
re.test('我的邮箱是abc@def.com,不是这个');
// true —— 但你可能只想验证整个字符串是邮箱
// 正确写法:要求整个字符串是邮箱
const reStrict = /^[a-z]+@[a-z]+\.[a-z]+$/;
reStrict.test('我的邮箱是abc@def.com');
// false —— 只有 "abc@def.com" 才会通过
错误2:. 不匹配换行符,导致多行文本匹配失败
const text = '第一行\n第二行';
text.match(/.+/.source); // ["第一行"] —— . 不匹配 \n
text.match(/.+/s.source); // ["第一行\n第二行"] —— s 标志让 . 匹配换行
text.match(/.+/gs.source); // ["第一行", "第二行"] —— 多行+全局
错误3:字符类里忘了转义,匹配到意外字符
// 想匹配点号,但点号在字符类外是正则特殊字符
const re1 = /[a.b]/; // 匹配 a、.、b 中的任意一个
const re2 = /[a\\.b]/; // 正确匹配字面点号,需要转义
// 想匹配 \ ,要写四个反斜杠
const re3 = /[\\]/; // 匹配反斜杠
错误4:量词位置错误导致匹配不符合预期
// 想匹配 1-100 的数字
const re = /[1-9]{1,2}|100/;
// 问题:| 优先级很低,等价于 ([1-9]{1,2}) | (100)
// "99" 通过,"100" 中的 "10" 也会先通过
// 正确:整体加括号控制优先级
const reFixed = /^([1-9]{1,2}|100)$/;
console.log(reFixed.test('99')); // true
console.log(reFixed.test('100')); // true
console.log(reFixed.test('101')); // false
console.log(reFixed.test('0')); // false
错误5:字符串转义陷阱(动态正则)
// 用户输入可能包含正则特殊字符,直接拼接会出错
const userInput = 'google.com'; // 用户可能输入的域名
const re = new RegExp('^' + userInput + '
常见问题
Q: 如何使用 正则表达式入门实例 相关工具?
A: 这类工具一般有明确的输入框和输出框,按提示输入内容,点击对应按钮即可得到结果。建议先用简单示例测试功能是否正常,再处理实际数据。
Q: 正则表达式入门实例 适合在什么场景使用?
A: 根据具体工具类型决定。格式转换工具适合处理第三方数据,编码工具适合加密传输,压缩工具适合文件上传前处理。多积累工具使用经验,遇到问题时能快速判断用哪个工具解决。
Q: 有没有更好的替代工具?
A: 不同工具有不同侧重,重点是理解原理。可以同时安装多个类似工具,实际使用中对比效果,选择最顺手的一个。随着使用经验增加,你也能判断工具的好坏。
);
// 生成的是 /^google.com$/ —— . 被当成了通配符
// "googleXcom" 也会匹配通过
// 正确:转义特殊字符
function escapeRegExp(str) {
return str.replace(/[.*+?^${}()|[\]\\]/g, '\\{{ARTICLE_CONTENT}}');
}
const reSafe = new RegExp('^' + escapeRegExp(userInput) + '
💡 遇到同类问题?用工具快速解决
试试这些配套工具,无需注册,打开即用
{{TOOL_LINKS}}
常见问题
{{FAQ_CONTENT}}
{{RELATED_QUESTIONS}}