三亩地 三亩地SAN MU DI · CODE DIARY
ARTICLE DETAIL

日记详情

真实记录编程学习的某一天,欢迎挑你感兴趣的翻一翻。

别再死记硬背了!用这5个真实JavaScript正则案例,搞定表单验证和字符串处理

别再死记硬背了!用这5个真实JavaScript正则案例,搞定表单验证和字符串处理

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

正则表达式就像程序员的瑞士军刀——看起来复杂,但一旦掌握就能解决各种字符串处理难题。很多初学者面对/^[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,}$/这样的模式时会直接放弃,其实只要通过实际案例拆解,你会发现它比想象中简单得多。本文将用5个真实场景带你突破正则表达式的学习瓶颈。

1. 用户注册表单的邮箱验证

邮箱验证是每个前端开发者最早遇到的正则需求。我们先看一个常见但不够严谨的写法:

function validateEmail(email) { return /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/.test(email); }

这个正则表达式有几个关键点:

  • ^表示字符串开始
  • [a-zA-Z0-9._-]+匹配用户名部分(1个或多个字符)
  • @必须包含的符号
  • [a-zA-Z0-9.-]+匹配域名部分
  • \.转义后的点号
  • [a-zA-Z]{2,4}$2到4个字母的顶级域名

但实际业务中我们需要更严格的验证:

// 加强版邮箱验证 const emailRegex = /^[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/i; // 测试用例 console.log(emailRegex.test('user@example.com')); // true console.log(emailRegex.test('user.name+tag@sub.domain.co.uk')); // true console.log(emailRegex.test('invalid@email')); // false

常见陷阱:

  • 忘记处理大小写(添加i修饰符)
  • 未考虑带点的用户名(如first.last@domain.com)
  • 未处理带加号的邮箱(如user+filter@gmail.com)

2. 手机号码的国际格式验证

不同国家的手机号格式差异很大,我们先从中国手机号开始:

// 简单的中国手机号验证 const cnMobileRegex = /^1[3-9]\d{9}$/; // 测试用例 console.log(cnMobileRegex.test('13800138000')); // true console.log(cnMobileRegex.test('12800138000')); // false(12开头无效)

更完善的国际手机号验证需要考虑:

// 国际手机号验证(简化版) const internationalMobileRegex = /^\+(?:[0-9] ?){6,14}[0-9]$/; // 测试用例 console.log(internationalMobileRegex.test('+86 138 0013 8000')); // true console.log(internationalMobileRegex.test('+1 (800) 555-1234')); // false(需要预处理)

实用技巧:

  • 在表单提交前先去除空格和特殊字符:
    function cleanPhoneNumber(phone) { return phone.replace(/[\s()-]/g, ''); }
  • 对于国际号码,建议使用专门的库如libphonenumber

3. 从文本中提取价格信息

电商网站经常需要从用户输入或文本中提取价格:

const text = "这款手机售价¥3999,限时优惠价$299.99,欧洲定价€349"; // 提取所有货币价格 const priceRegex = /[¥$€]\d+(?:\.\d{1,2})?/g; const prices = text.match(priceRegex); console.log(prices); // ["¥3999", "$299.99", "€349"]

更复杂的场景可能需要:

// 提取带千位分隔符的价格 const complexPriceRegex = /[¥$€]\d{1,3}(?:,\d{3})*(?:\.\d{1,2})?/g; console.log("价格$1,234,567.89".match(complexPriceRegex)); // ["$1,234,567.89"]

处理技巧:

  • 将提取的价格转换为数字:
    function priceToNumber(priceStr) { return parseFloat(priceStr.replace(/[^\d.]/g, '')); }
  • 注意不同地区小数点表示法(欧洲常用逗号)

4. 日期格式的转换与验证

处理用户输入的日期是常见需求,我们先看简单的格式验证:

// 验证YYYY-MM-DD格式 const dateRegex = /^\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])$/; console.log(dateRegex.test('2023-02-28')); // true console.log(dateRegex.test('2023-02-30')); // true(需要额外逻辑验证)

更实用的日期处理函数:

function formatDate(input, fromFormat, toFormat) { // 解析各种输入格式 const patterns = { 'YYYY-MM-DD': /^(\d{4})-(\d{2})-(\d{2})$/, 'DD/MM/YYYY': /^(\d{2})\/(\d{2})\/(\d{4})$/, 'MM-DD-YYYY': /^(\d{2})-(\d{2})-(\d{4})$/ }; const match = input.match(patterns[fromFormat]); if (!match) return null; // 转换为目标格式 return toFormat .replace('YYYY', match[1] || match[3]) .replace('MM', match[2]) .replace('DD', match[3] || match[1]); } console.log(formatDate('28/02/2023', 'DD/MM/YYYY', 'YYYY-MM-DD')); // "2023-02-28"

注意事项:

  • 正则表达式只能验证格式,不能验证日期有效性(如2月30日)
  • 考虑使用Date对象进行进一步验证
  • 时区问题需要特别注意

5. 富文本内容的安全过滤

用户生成内容(UGC)需要过滤危险标签和属性:

function sanitizeHTML(html) { // 允许的基本标签和属性 const allowedTags = /^(p|br|a|strong|em|ul|ol|li|h[1-6])$/; const allowedAttrs = /^(href|title|target)$/; return html.replace(/<(\/?)([a-z][a-z0-9]*)([^>]*?)>/gi, (match, slash, tag, attrs) => { if (!allowedTags.test(tag)) return ''; const filteredAttrs = attrs.replace( /([a-z-]+)=(["'])(.*?)\2/gi, (attrMatch, name, quote, value) => { return allowedAttrs.test(name) ? attrMatch : ''; } ); return `<${slash}${tag}${filteredAttrs}>`; }); } const dirtyHTML = '<p>正常内容</p><script>alert("危险")</script><a href="#" onclick="malicious()">链接</a>'; console.log(sanitizeHTML(dirtyHTML)); // "<p>正常内容</p><a href="#">链接</a>"

进阶方案:

  • 对于复杂场景,推荐使用专门的库如DOMPurify
  • 始终在服务端进行二次验证
  • 注意style属性中的XSS风险

正则表达式调试技巧

即使掌握了语法,调试复杂的正则表达式仍然具有挑战性。以下是几个实用工具和方法:

  1. 可视化工具:

    • Regex101 提供实时测试和解释
    • RegExr 适合学习和调试
  2. JavaScript控制台技巧:

    // 查看正则表达式的匹配细节 const regex = /(\d{4})-(\d{2})-(\d{2})/; const result = regex.exec('2023-05-15'); console.log(result); // ["2023-05-15", "2023", "05", "15", ...]
  3. 性能优化建议:

    • 避免过度使用回溯(.*?)
    • 预编译常用正则表达式:
      // 不好的写法 function testSomething(input) { return /[a-z]+/.test(input); } // 好的写法 const testRegex = /[a-z]+/; function testSomething(input) { return testRegex.test(input); }
  4. 常见性能陷阱:

    // 灾难性回溯示例(极慢) const badRegex = /(a+)+$/; console.log(badRegex.test('aaaaaaaaaaaaaaaaaaaaaaaaaaaaa!'));

掌握这些实战案例后,你会发现正则表达式不再是令人畏惧的"黑魔法",而是日常开发中的得力助手。关键在于从实际需求出发,先解决具体问题,再逐步深入理解各种语法规则。

← 返回列表