5个JavaScript正则表达式实战案例:从表单验证到文本处理

正则表达式就像程序员的瑞士军刀——看起来复杂,但一旦掌握就能解决各种字符串处理难题。很多初学者面对 /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/ 这样的"天书"直接选择放弃,转而到处复制粘贴。但当你真正理解它的工作原理后,会发现这比死记硬背要高效得多。本文将用5个真实开发场景,带你感受正则表达式在前端开发中的实际威力。

1. 用户注册表单验证三部曲

1.1 邮箱验证:比你想的更复杂

大多数教程教的邮箱正则都很基础,比如 /\w+@\w+\.\w+/ ,这在实际项目中远远不够。考虑以下合法邮箱:

  • 带点的 john.doe@example.com
  • 带加号的 john+filter@example.com
  • 国际域名 用户@例子.中国

一个健壮的邮箱验证正则应该这样写:

const emailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;

// 测试用例
console.log(emailRegex.test('john.doe@example.com')); // true
console.log(emailRegex.test('john+newsletter@sub.example.co.uk')); // true
console.log(emailRegex.test('invalid@email')); // false

关键点解析

  • ^ $ 确保匹配整个字符串
  • [a-zA-Z0-9._%+-]+ 匹配用户名部分
  • @ 后接域名部分 [a-zA-Z0-9.-]+
  • \. 转义点号, [a-zA-Z]{2,} 匹配顶级域名

1.2 手机号验证:考虑国际格式

中国手机号验证看似简单,但实际需要考虑:

  • 11位数字
  • 以1开头
  • 第二位通常是3-9
const phoneRegex = /^1[3-9]\d{9}$/;

// 改进版:允许带空格或连字符
const phoneRegexEnhanced = /^1[3-9][\s-]?\d{4}[\s-]?\d{4}$/;

注意:实际项目中应考虑服务端二次验证,前端验证仅用于提升用户体验

1.3 密码强度校验

要求密码包含大小写字母、数字和特殊字符,长度8-20位:

const passwordRegex = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,20}$/;

这个正则使用了 正向预查

  • (?=.*[a-z]) 确保至少一个小写字母
  • (?=.*[A-Z]) 确保至少一个大写字母
  • (?=.*\d) 确保至少一个数字
  • (?=.*[@$!%*?&]) 确保至少一个特殊字符

2. 从文本中提取结构化数据

2.1 抓取商品价格

用户输入的文本中可能包含各种价格格式:

  • ¥199
  • $19.99
  • 仅数字 299
const text = "这款手机售价¥3999,限时优惠$299.99";
const priceRegex = /[¥$]\d+(?:\.\d{1,2})?|\b\d+\b/g;

const prices = text.match(priceRegex);
console.log(prices); // ["¥3999", "$299.99"]

2.2 提取日期信息

处理各种日期格式:

  • 2023-08-15
  • 2023/08/15
  • 15-Aug-2023
const dateRegex = /\b(?:\d{4}[-/]\d{1,2}[-/]\d{1,2}|\d{1,2}-[A-Za-z]{3}-\d{4})\b/g;

const dates = "会议时间2023-08-15或15-Aug-2023".match(dateRegex);
console.log(dates); // ["2023-08-15", "15-Aug-2023"]

3. 文本清洗与格式化

3.1 去除HTML标签

从富文本中提取纯文本:

function stripHtml(html) {
  return html.replace(/<[^>]+>/g, '');
}

console.log(stripHtml('<p>Hello <b>world</b>!</p>')); // "Hello world!"

3.2 敏感词过滤

实现简单的敏感词替换:

const sensitiveWords = ['暴力', '色情', '赌博'];
const regex = new RegExp(sensitiveWords.join('|'), 'gi');

function filterText(text) {
  return text.replace(regex, '***');
}

console.log(filterText("禁止暴力内容")); // "禁止***内容"

4. 高级字符串操作

4.1 驼峰命名转换

将CSS样式属性转换为驼峰命名:

function toCamelCase(str) {
  return str.replace(/-([a-z])/g, (_, letter) => letter.toUpperCase());
}

console.log(toCamelCase('background-color')); // "backgroundColor"

4.2 千位分隔符

为数字添加千位分隔符:

function formatNumber(num) {
  return num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
}

console.log(formatNumber(1234567.89)); // "1,234,567.89"

5. 实战项目:表单验证综合应用

结合上述技术,实现一个完整的注册表单验证:

class FormValidator {
  static patterns = {
    username: /^[a-zA-Z0-9_]{4,16}$/,
    email: /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/,
    phone: /^1[3-9]\d{9}$/,
    password: /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).{8,}$/
  };

  static validate(field, value) {
    const pattern = this.patterns[field];
    if (!pattern) return true;
    
    return pattern.test(value);
  }

  static getErrorMessage(field) {
    const messages = {
      username: '4-16位字母、数字或下划线',
      email: '请输入有效的邮箱地址',
      phone: '请输入有效的手机号',
      password: '至少8位,包含大小写字母和数字'
    };
    
    return messages[field] || '输入无效';
  }
}

// 使用示例
console.log(FormValidator.validate('email', 'test@example.com')); // true
console.log(FormValidator.getErrorMessage('password')); 
// "至少8位,包含大小写字母和数字"

调试技巧

  1. 使用 RegExr 等工具实时测试
  2. 拆解复杂正则,逐步构建
  3. 编写全面的测试用例
  4. 善用 console.log 查看匹配结果

正则表达式的学习曲线确实陡峭,但一旦掌握就能极大提升开发效率。建议从简单模式开始,逐步增加复杂度,遇到问题时多查阅 MDN正则文档

更多推荐