正则表达式入门实例

← 返回工具首页

正则表达式入门与实例:用JavaScript搞定文本校验

你一定见过这种场景:用户在注册表单里填了个 abc@def,你想拦却拦不住;后端传来一串手机号,你肉眼看不出是不是多了个空格;领导让你从一段日志里提取所有 IP 地址,你只能一行行复制粘贴。这些问题,正则表达式(Regular Expression,简称 regex)一个模式就能解决。

正则表达式是程序员的文本瑞士军刀。无论是表单验证、日志分析、数据清洗还是 URL 路由匹配,它都是首选工具。本文用 JavaScript(ES6+) 做示例,覆盖从语法基础到实战避坑,帮助你真正上手。

一、正则能解决什么问题?

先把痛点说清楚。正则表达式的核心能力就三个:

没有正则的时候,你可能要写一堆 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

解释:

示例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}} ); reSafe.test('google.com'); // true reSafe.test('googleXcom'); // false

错误6:捕获组编号搞混,特别是替换时

// 替换时 $1 $2 指的顺序是括号出现顺序,不是内容顺序
const html = '<span>Hello</span>';
// 想替换标签为 div,但结果不对
html.replace(/<(\w+)>(.*?)<\/\1>/, '<div>$2</div>');
// 结果: "<div>Hello</div>" —— 正确!\1 引用 (<span>) 的标签名

// 如果有嵌套捕获组,按左括号顺序数
'

六、RegExp 常用方法速查

// test() —— 返回布尔值,最快判断是否匹配
/\d+/.test('abc123'); // true

// exec() —— 返回匹配详情(含捕获组、索引位置),全局下可反复调用
const re = /\d+/g;
let m;
while ((m = re.exec('a1b2c3')) !== null) {
  console.log('匹配到:', m[0], '位置:', m.index);
}

// match() —— 字符串方法,全局下返回所有匹配数组,非全局返回 exec 类似结果
'a1b2c3'.match(/\d/g);     // ["1","2","3"]
'a1b2c3'.match(/(\d)/g);   // ["1","2","3"] —— capture group 不影响全局结果
'a1b2c3'.match(/\d/);      // ["1", index: 1, ...] 非全局返回详细信息

// replace() —— 字符串方法,支持捕获组和函数替换
'Hello World'.replace(/(\w+)\s(\w+)/, '$2 $1'); // "World Hello"
'price: 100'.replace(/\d+/, m => '

      

💡 遇到同类问题?用工具快速解决

试试这些配套工具,无需注册,打开即用

{{TOOL_LINKS}}

常见问题

{{FAQ_CONTENT}}
{{RELATED_QUESTIONS}}
+ m); // "price: $100"

七、学习建议与进阶路径

正则不难,但需要动手练习。不要光看,一定要写。

八、在线练习与工具推荐

看得懂不代表写得对。正则一定要动手试。

推荐使用 CloverTools 的 正则表达式测试器,支持实时匹配、捕获组高亮、JavaScript 代码导出,可以边写边验证,遇到复杂模式时特别有用。


正则表达式是每个开发者都应该掌握的基础技能。学会它,数据校验从烦琐变优雅,文本处理从手工变自动。从今天开始,少用字符串拼接,多用正则模式,你会发现代码质量和效率都会上一个台阶。

💡 遇到同类问题?用工具快速解决

试试这些配套工具,无需注册,打开即用

{{TOOL_LINKS}}

常见问题

{{FAQ_CONTENT}}
{{RELATED_QUESTIONS}}