活动公告

系统通知
05-18 21:22
系统通知
通知:本站资源由网友上传分享,如有违规等问题请到版务模块进行投诉,资源失效请在帖子内回复要求补档,会尽快处理!
10-23 09:31

掌握JavaScript正则表达式从入门到精通 实用技巧与常见问题解决方案 提升代码效率的必备指南

SunJu_FaceMall

3万

主题

2860

科技点

3万

积分

白金月票

碾压王

积分
32872

塔罗立华奏

<font color=白金月票" /> 发表于 2025-8-31 22:10:01 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
引言

正则表达式是处理文本的强大工具,在JavaScript中广泛应用于表单验证、数据提取、文本替换等场景。掌握正则表达式可以大大提升代码效率和开发体验。本文将从基础概念讲起,逐步深入到高级技巧和常见问题解决方案,帮助读者全面掌握JavaScript正则表达式。

正则表达式基础

正则表达式(Regular Expression)是一种用于描述字符串模式的工具。它由普通字符(如字母、数字)和特殊字符(称为”元字符”)组成,可以用来检查一个字符串是否含有某种模式、将匹配的pattern替换掉或者从某个字符串中取出符合某个子模式的字符串等。

基本语法

正则表达式由一系列字符和元字符组成。以下是一些基本的元字符:

• .:匹配除换行符以外的任意字符
• \d:匹配数字,等价于[0-9]
• \D:匹配非数字,等价于[^0-9]
• \w:匹配字母、数字、下划线,等价于[a-zA-Z0-9_]
• \W:匹配非字母、数字、下划线,等价于[^a-zA-Z0-9_]
• \s:匹配空白字符,包括空格、制表符、换行符等
• \S:匹配非空白字符
• ^:匹配字符串的开始
• $:匹配字符串的结束
• *:匹配前面的子表达式零次或多次
• +:匹配前面的子表达式一次或多次
• ?:匹配前面的子表达式零次或一次
• {n}:匹配前面的子表达式恰好n次
• {n,}:匹配前面的子表达式至少n次
• {n,m}:匹配前面的子表达式至少n次,最多m次

字符类

字符类用于匹配一组字符中的一个。可以使用方括号[]来定义字符类:

• [abc]:匹配a、b或c中的任意一个字符
• [^abc]:匹配除了a、b、c之外的任意字符
• [a-z]:匹配a到z之间的任意小写字母
• [A-Z]:匹配A到Z之间的任意大写字母
• [0-9]:匹配0到9之间的任意数字

分组和引用

使用圆括号()可以对正则表达式进行分组,分组后的表达式可以作为一个整体进行量词操作,也可以在后续进行引用:

• (pattern):匹配pattern并捕获匹配,可以使用\1、\2等引用
• (?:pattern):匹配pattern但不捕获匹配
• (?=pattern):正向预查,匹配pattern前面的位置
• (?!pattern):负向预查,匹配不在pattern前面的位置

JavaScript中的正则表达式

在JavaScript中,正则表达式可以通过两种方式创建:字面量和构造函数。

创建正则表达式
  1. const pattern = /pattern/flags;
复制代码
  1. const pattern = new RegExp('pattern', 'flags');
复制代码

其中,flags是可选的修饰符,包括:

• g:全局匹配,找到所有匹配项,而不是在找到第一个匹配项后停止
• i:忽略大小写
• m:多行模式,^和$可以匹配每行的开始和结束
• u:Unicode模式,正确处理UTF-16编码的字符
• y:粘滞模式,只从目标字符串的当前位置开始匹配

正则表达式方法

JavaScript中的RegExp对象提供了几个方法用于执行匹配操作:

test()方法用于测试字符串是否匹配正则表达式,返回true或false。
  1. const pattern = /hello/;
  2. console.log(pattern.test('hello world')); // true
  3. console.log(pattern.test('hi world'));    // false
复制代码

exec()方法用于执行匹配,返回匹配结果的数组,如果没有匹配则返回null。
  1. const pattern = /(\d{4})-(\d{2})-(\d{2})/;
  2. const result = pattern.exec('Date: 2023-07-15');
  3. console.log(result);
  4. // 输出: ["2023-07-15", "2023", "07", "15", index: 6, input: "Date: 2023-07-15", groups: undefined]
复制代码

字符串方法

JavaScript中的String对象也提供了几个接受正则表达式作为参数的方法:

match()方法用于检索字符串中与正则表达式匹配的结果,返回一个数组,如果没有匹配则返回null。
  1. const str = 'The quick brown fox jumps over the lazy dog.';
  2. const pattern = /the/gi;
  3. console.log(str.match(pattern));
  4. // 输出: ["The", "the"]
复制代码

search()方法用于检索字符串中与正则表达式匹配的子串的起始位置,如果没有匹配则返回-1。
  1. const str = 'The quick brown fox jumps over the lazy dog.';
  2. const pattern = /fox/i;
  3. console.log(str.search(pattern)); // 输出: 16
复制代码

replace()方法用于替换字符串中与正则表达式匹配的子串。
  1. const str = 'The quick brown fox jumps over the lazy dog.';
  2. const pattern = /fox/i;
  3. console.log(str.replace(pattern, 'cat'));
  4. // 输出: "The quick brown cat jumps over the lazy dog."
复制代码

split()方法用于将字符串分割为字符串数组。
  1. const str = 'apple, banana, orange, grape';
  2. const pattern = /\s*,\s*/;
  3. console.log(str.split(pattern));
  4. // 输出: ["apple", "banana", "orange", "grape"]
复制代码

正则表达式属性

JavaScript中的RegExp对象有几个属性可以提供关于正则表达式的信息:

• source:返回正则表达式的文本
• flags:返回正则表达式的修饰符
• global:检查是否设置了”g”修饰符
• ignoreCase:检查是否设置了”i”修饰符
• multiline:检查是否设置了”m”修饰符
• unicode:检查是否设置了”u”修饰符
• sticky:检查是否设置了”y”修饰符
• lastIndex:返回或设置要匹配的起始位置
  1. const pattern = /test/gi;
  2. console.log(pattern.source);     // 输出: "test"
  3. console.log(pattern.flags);      // 输出: "gi"
  4. console.log(pattern.global);     // 输出: true
  5. console.log(pattern.ignoreCase); // 输出: true
  6. console.log(pattern.multiline);  // 输出: false
复制代码

常用正则表达式模式

在实际开发中,有一些常用的正则表达式模式可以帮助我们快速解决常见问题。

数字相关
  1. // 正整数
  2. const positiveInteger = /^[1-9]\d*$/;
  3. console.log(positiveInteger.test('123'));    // true
  4. console.log(positiveInteger.test('0123'));   // false
  5. console.log(positiveInteger.test('-123'));   // false
  6. // 负整数
  7. const negativeInteger = /^-[1-9]\d*$/;
  8. console.log(negativeInteger.test('-123'));   // true
  9. console.log(negativeInteger.test('123'));    // false
  10. console.log(negativeInteger.test('-0123'));  // false
  11. // 整数(包括正整数、负整数和0)
  12. const integer = /^(0|-?[1-9]\d*)$/;
  13. console.log(integer.test('0'));      // true
  14. console.log(integer.test('123'));    // true
  15. console.log(integer.test('-123'));   // true
  16. console.log(integer.test('0123'));   // false
复制代码
  1. // 正浮点数
  2. const positiveFloat = /^[1-9]\d*\.\d+$|^0\.\d+$/;
  3. console.log(positiveFloat.test('3.14'));    // true
  4. console.log(positiveFloat.test('0.14'));    // true
  5. console.log(positiveFloat.test('123'));     // false
  6. console.log(positiveFloat.test('-3.14'));   // false
  7. // 负浮点数
  8. const negativeFloat = /^-[1-9]\d*\.\d+$|^-0\.\d+$/;
  9. console.log(negativeFloat.test('-3.14'));   // true
  10. console.log(negativeFloat.test('-0.14'));   // true
  11. console.log(negativeFloat.test('3.14'));    // false
  12. // 浮点数(包括正浮点数、负浮点数和0)
  13. const float = /^(0|-?[1-9]\d*)(\.\d+)?$/;
  14. console.log(float.test('0'));       // true
  15. console.log(float.test('3.14'));    // true
  16. console.log(float.test('-3.14'));   // true
  17. console.log(float.test('0.14'));    // true
  18. console.log(float.test('-0.14'));   // true
  19. console.log(float.test('123'));     // true
  20. console.log(float.test('-123'));    // true
复制代码
  1. // 0-100之间的数字,可以包含两位小数
  2. const range0to100 = /^(100|0?\d(\.\d{1,2})?)$/;
  3. console.log(range0to100.test('0'));      // true
  4. console.log(range0to100.test('100'));    // true
  5. console.log(range0to100.test('50.5'));   // true
  6. console.log(range0to100.test('50.55'));  // true
  7. console.log(range0to100.test('50.555')); // false
  8. console.log(range0to100.test('101'));    // false
复制代码

字符串相关
  1. const email = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
  2. console.log(email.test('example@example.com'));     // true
  3. console.log(email.test('example@example.co.uk'));   // true
  4. console.log(email.test('example@example'));         // false
  5. console.log(email.test('example.com'));             // false
复制代码
  1. // 简单的中国手机号验证
  2. const phone = /^1[3-9]\d{9}$/;
  3. console.log(phone.test('13812345678'));   // true
  4. console.log(phone.test('15812345678'));   // true
  5. console.log(phone.test('10812345678'));   // false
  6. console.log(phone.test('1381234567'));    // false
复制代码
  1. const url = /^(https?:\/\/)?([\da-z.-]+)\.([a-z.]{2,6})([/\w .-]*)*\/?$/;
  2. console.log(url.test('http://www.example.com'));      // true
  3. console.log(url.test('https://www.example.com'));     // true
  4. console.log(url.test('www.example.com'));             // true
  5. console.log(url.test('example.com'));                 // true
  6. console.log(url.test('http://example.com/path'));     // true
  7. console.log(url.test('http://example.com/path?query=param'));  // true
  8. console.log(url.test('ftp://example.com'));           // false
复制代码
  1. // 简单的中国身份证号验证(15位或18位)
  2. const idCard = /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/;
  3. console.log(idCard.test('123456789012345'));    // true
  4. console.log(idCard.test('123456789012345678'));  // true
  5. console.log(idCard.test('12345678901234567X'));  // true
  6. console.log(idCard.test('1234567890123456'));    // false
复制代码
  1. // 至少包含一个大写字母、一个小写字母、一个数字和一个特殊字符,长度在8-20之间
  2. const strongPassword = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,20}$/;
  3. console.log(strongPassword.test('Password123!'));     // true
  4. console.log(strongPassword.test('password123!'));     // false (缺少大写字母)
  5. console.log(strongPassword.test('PASSWORD123!'));     // false (缺少小写字母)
  6. console.log(strongPassword.test('Password!'));        // false (缺少数字)
  7. console.log(strongPassword.test('Password123'));      // false (缺少特殊字符)
  8. console.log(strongPassword.test('Pass1!'));           // false (长度太短)
复制代码

日期和时间
  1. const date = /^\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])$/;
  2. console.log(date.test('2023-07-15'));    // true
  3. console.log(date.test('2023-02-28'));    // true
  4. console.log(date.test('2023-02-29'));    // true (不考虑闰年)
  5. console.log(date.test('2023-13-15'));    // false
  6. console.log(date.test('2023-07-32'));    // false
  7. console.log(date.test('2023-7-15'));     // false
复制代码
  1. const time = /^([01]\d|2[0-3]):([0-5]\d):([0-5]\d)$/;
  2. console.log(time.test('12:34:56'));     // true
  3. console.log(time.test('23:59:59'));     // true
  4. console.log(time.test('00:00:00'));     // true
  5. console.log(time.test('24:00:00'));     // false
  6. console.log(time.test('12:60:00'));     // false
  7. console.log(time.test('12:34:5'));      // false
复制代码

高级技巧

掌握了基础知识和常用模式后,我们来学习一些高级技巧,这些技巧可以帮助我们更灵活地使用正则表达式。

贪婪与非贪婪匹配

默认情况下,正则表达式是贪婪的,会尽可能多地匹配字符。通过在量词后面加上?,可以使其变为非贪婪模式,尽可能少地匹配字符。
  1. const str = '<div>content1</div><div>content2</div>';
  2. // 贪婪匹配
  3. const greedyPattern = /<div>.*<\/div>/;
  4. console.log(str.match(greedyPattern)[0]);
  5. // 输出: "<div>content1</div><div>content2</div>"
  6. // 非贪婪匹配
  7. const nonGreedyPattern = /<div>.*?<\/div>/;
  8. console.log(str.match(nonGreedyPattern)[0]);
  9. // 输出: "<div>content1</div>"
复制代码

回溯

回溯是正则表达式引擎的一种工作方式,当有多种匹配可能时,引擎会尝试一种可能,如果后续匹配失败,则回退到之前的状态尝试其他可能。虽然回溯是强大的,但也可能导致性能问题。
  1. const str = 'aaaaaaaaaaaaaaaaaaaaX';
  2. // 这个正则表达式会导致大量的回溯
  3. const problematicPattern = /^(a+)+$/;
  4. console.log(problematicPattern.test(str)); // true,但可能会很慢
  5. // 优化后的正则表达式
  6. const optimizedPattern = /^a+$/;
  7. console.log(optimizedPattern.test(str)); // true,且速度快
复制代码

断言

断言用于匹配某些位置,而不是实际的字符。JavaScript支持正向断言和负向断言。

正向先行断言(?=pattern)表示匹配的位置后面必须跟着pattern,但不包括在匹配结果中。
  1. const str = 'windows10 windows11 windows12';
  2. // 匹配后面跟着数字的windows
  3. const pattern = /windows(?=\d+)/g;
  4. console.log(str.match(pattern));
  5. // 输出: ["windows", "windows", "windows"]
复制代码

负向先行断言(?!pattern)表示匹配的位置后面不能跟着pattern。
  1. const str = 'windows10 windowsX windows12';
  2. // 匹配后面不跟着数字的windows
  3. const pattern = /windows(?!\d+)/g;
  4. console.log(str.match(pattern));
  5. // 输出: ["windowsX"]
复制代码

ES2018引入了正向后行断言(?<=pattern),表示匹配的位置前面必须是pattern,但不包括在匹配结果中。
  1. const str = '$10 $20 $30';
  2. // 匹配前面是$的数字
  3. const pattern = /(?<=\$)\d+/g;
  4. console.log(str.match(pattern));
  5. // 输出: ["10", "20", "30"]
复制代码

ES2018也引入了负向后行断言(?<!pattern),表示匹配的位置前面不能是pattern。
  1. const str = '10 $20 30';
  2. // 匹配前面不是$的数字
  3. const pattern = /(?<!\$)\d+/g;
  4. console.log(str.match(pattern));
  5. // 输出: ["10", "30"]
复制代码

捕获组和非捕获组

圆括号()可以创建捕获组,匹配的内容会被记住,可以通过\1、\2等方式引用,或者在结果数组中获取。如果不需要捕获匹配的内容,可以使用非捕获组(?:pattern)。
  1. const str = '2023-07-15';
  2. // 使用捕获组
  3. const capturingPattern = /(\d{4})-(\d{2})-(\d{2})/;
  4. const result = capturingPattern.exec(str);
  5. console.log(result[1]); // 输出: "2023"
  6. console.log(result[2]); // 输出: "07"
  7. console.log(result[3]); // 输出: "15"
  8. // 使用非捕获组
  9. const nonCapturingPattern = /(?:\d{4})-(\d{2})-(\d{2})/;
  10. const result2 = nonCapturingPattern.exec(str);
  11. console.log(result2[1]); // 输出: "07"
  12. console.log(result2[2]); // 输出: "15"
复制代码

命名捕获组

ES2018引入了命名捕获组,可以使用(?<name>pattern)的语法为捕获组命名,使代码更易读。
  1. const str = '2023-07-15';
  2. // 使用命名捕获组
  3. const namedPattern = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/;
  4. const result = namedPattern.exec(str);
  5. console.log(result.groups.year);  // 输出: "2023"
  6. console.log(result.groups.month); // 输出: "07"
  7. console.log(result.groups.day);   // 输出: "15"
复制代码

原子组

原子组(?>pattern)是一旦匹配就不会回退的组,可以提高正则表达式的性能,避免不必要的回溯。
  1. const str = 'aaaaaaaaaaaaaaaaaaaaX';
  2. // 使用原子组防止回溯
  3. const atomicPattern = /^(?>a+)+$/;
  4. console.log(atomicPattern.test(str)); // true,且速度快
复制代码

性能优化

正则表达式虽然强大,但如果使用不当,可能会导致性能问题。以下是一些优化正则表达式性能的技巧。

避免回溯

回溯是正则表达式性能问题的常见原因。以下是一些避免回溯的技巧:

1. 使用具体字符代替.,因为.会匹配除换行符外的任何字符,可能导致大量回溯。
2. 使用原子组(?>pattern)防止回溯。
3. 使用占有量词*+、++、?+、{n,m}+,这些量词一旦匹配就不会回退。
  1. // 不好的写法,可能导致大量回溯
  2. const badPattern = /^(a+)+$/;
  3. // 好的写法,避免回溯
  4. const goodPattern = /^a+$/;
复制代码

使用非捕获组

如果不需要引用匹配的内容,使用非捕获组(?:pattern)代替捕获组(),可以提高性能。
  1. // 不好的写法,使用捕获组
  2. const badPattern = /(\d{4})-(\d{2})-(\d{2})/;
  3. // 好的写法,使用非捕获组
  4. const goodPattern = /(?:\d{4})-(?:\d{2})-(?:\d{2})/;
复制代码

使用具体字符类

使用具体的字符类代替.或\w等通用字符类,可以减少匹配的可能性,提高性能。
  1. // 不好的写法,使用通用字符类
  2. const badPattern = /^.+@.+\..+$/;
  3. // 好的写法,使用具体字符类
  4. const goodPattern = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
复制代码

避免嵌套量词

嵌套量词如(a+)*会导致指数级的回溯,应该避免使用。
  1. // 不好的写法,使用嵌套量词
  2. const badPattern = /^(a+)*$/;
  3. // 好的写法,避免嵌套量词
  4. const goodPattern = /^a*$/;
复制代码

使用锚点

使用^和$锚点可以限制匹配的位置,避免不必要的匹配尝试。
  1. // 不好的写法,没有使用锚点
  2. const badPattern = /\d{4}-\d{2}-\d{2}/;
  3. // 好的写法,使用锚点
  4. const goodPattern = /^\d{4}-\d{2}-\d{2}$/;
复制代码

预编译正则表达式

如果正则表达式会被多次使用,可以预编译正则表达式,避免重复解析。
  1. // 不好的写法,每次使用都重新解析
  2. function validateEmail(email) {
  3.   return /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/.test(email);
  4. }
  5. // 好的写法,预编译正则表达式
  6. const emailPattern = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
  7. function validateEmail(email) {
  8.   return emailPattern.test(email);
  9. }
复制代码

常见问题与解决方案

在使用正则表达式时,我们可能会遇到一些常见问题。下面是一些常见问题及其解决方案。

问题1:匹配特殊字符

正则表达式中的许多字符具有特殊含义,如.,*,+,?,|,\,(,),[,],{,},^,$。如果要匹配这些字符本身,需要使用反斜杠\进行转义。
  1. const str = '3.14 * 2 = 6.28';
  2. // 不好的写法,没有转义特殊字符
  3. const badPattern = /./;
  4. console.log(str.match(badPattern));
  5. // 输出: ["3", index: 0, input: "3.14 * 2 = 6.28", groups: undefined]
  6. // 好的写法,转义特殊字符
  7. const goodPattern = /\./;
  8. console.log(str.match(goodPattern));
  9. // 输出: [".", index: 1, input: "3.14 * 2 = 6.28", groups: undefined]
复制代码

问题2:匹配换行符

默认情况下,.不匹配换行符。如果要匹配包括换行符在内的任意字符,可以使用[\s\S]或设置s标志(dotAll模式)。
  1. const str = 'Line 1\nLine 2';
  2. // 不好的写法,.不匹配换行符
  3. const badPattern = /Line 1.*Line 2/;
  4. console.log(badPattern.test(str)); // false
  5. // 好的写法1,使用[\s\S]匹配任意字符
  6. const goodPattern1 = /Line 1[\s\S]*Line 2/;
  7. console.log(goodPattern1.test(str)); // true
  8. // 好的写法2,使用s标志(dotAll模式)
  9. const goodPattern2 = /Line 1.*Line 2/s;
  10. console.log(goodPattern2.test(str)); // true
复制代码

问题3:匹配单词边界

单词边界\b匹配单词和非单词之间的位置,可以用来精确匹配单词。
  1. const str = 'The cat scattered his food all over the floor.';
  2. // 不好的写法,会匹配到"cat"和"scattered"中的"cat"
  3. const badPattern = /cat/;
  4. console.log(str.match(badPattern));
  5. // 输出: ["cat", index: 4, input: "The cat scattered his food all over the floor.", groups: undefined]
  6. // 好的写法,使用单词边界精确匹配"cat"
  7. const goodPattern = /\bcat\b/;
  8. console.log(str.match(goodPattern));
  9. // 输出: ["cat", index: 4, input: "The cat scattered his food all over the floor.", groups: undefined]
复制代码

问题4:处理Unicode字符

JavaScript中的正则表达式默认是基于16位UTF-16编码的,这可能导致处理一些Unicode字符时出现问题。使用u标志可以启用Unicode模式。
  1. const str = '😊';
  2. // 不好的写法,不能正确匹配emoji
  3. const badPattern = /^.$/;
  4. console.log(badPattern.test(str)); // false
  5. // 好的写法,使用u标志启用Unicode模式
  6. const goodPattern = /^.$/u;
  7. console.log(goodPattern.test(str)); // true
复制代码

问题5:调试正则表达式

调试正则表达式可能比较困难,以下是一些调试技巧:

1. 使用在线正则表达式测试工具,如regex101.com、regexr.com等。
2. 使用RegExp.prototype.toString()方法查看正则表达式的字符串表示。
3. 使用console.log()输出匹配结果,逐步调试。
  1. const pattern = /(\d{4})-(\d{2})-(\d{2})/;
  2. const str = 'Date: 2023-07-15';
  3. // 输出正则表达式的字符串表示
  4. console.log(pattern.toString()); // 输出: "/(\d{4})-(\d{2})-(\d{2})/"
  5. // 输出匹配结果
  6. const result = pattern.exec(str);
  7. console.log(result);
  8. // 输出: ["2023-07-15", "2023", "07", "15", index: 6, input: "Date: 2023-07-15", groups: undefined]
复制代码

实战案例

下面是一些实际项目中使用正则表达式的案例。

案例1:表单验证
  1. // 验证表单数据
  2. function validateForm(formData) {
  3.   const errors = {};
  4.   
  5.   // 验证用户名:4-16位字母、数字、下划线
  6.   const usernamePattern = /^[a-zA-Z0-9_]{4,16}$/;
  7.   if (!usernamePattern.test(formData.username)) {
  8.     errors.username = '用户名必须是4-16位字母、数字、下划线';
  9.   }
  10.   
  11.   // 验证邮箱
  12.   const emailPattern = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
  13.   if (!emailPattern.test(formData.email)) {
  14.     errors.email = '请输入有效的邮箱地址';
  15.   }
  16.   
  17.   // 验证手机号
  18.   const phonePattern = /^1[3-9]\d{9}$/;
  19.   if (!phonePattern.test(formData.phone)) {
  20.     errors.phone = '请输入有效的手机号';
  21.   }
  22.   
  23.   // 验证密码:至少包含一个大写字母、一个小写字母、一个数字和一个特殊字符,长度在8-20之间
  24.   const passwordPattern = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,20}$/;
  25.   if (!passwordPattern.test(formData.password)) {
  26.     errors.password = '密码必须包含大小写字母、数字和特殊字符,长度在8-20之间';
  27.   }
  28.   
  29.   // 验证身份证号
  30.   const idCardPattern = /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/;
  31.   if (!idCardPattern.test(formData.idCard)) {
  32.     errors.idCard = '请输入有效的身份证号';
  33.   }
  34.   
  35.   return {
  36.     isValid: Object.keys(errors).length === 0,
  37.     errors
  38.   };
  39. }
  40. // 使用示例
  41. const formData = {
  42.   username: 'user123',
  43.   email: 'user@example.com',
  44.   phone: '13812345678',
  45.   password: 'Password123!',
  46.   idCard: '123456789012345678'
  47. };
  48. const validation = validateForm(formData);
  49. console.log(validation.isValid); // true
  50. console.log(validation.errors);  // {}
复制代码

案例2:数据提取
  1. // 从HTML中提取所有链接
  2. function extractLinks(html) {
  3.   const linkPattern = /<a\s+(?:[^>]*?\s+)?href="([^"]*)"/gi;
  4.   const links = [];
  5.   let match;
  6.   
  7.   while ((match = linkPattern.exec(html)) !== null) {
  8.     links.push(match[1]);
  9.   }
  10.   
  11.   return links;
  12. }
  13. // 使用示例
  14. const html = `
  15. <html>
  16.   <body>
  17.     <a href="https://example.com">Example</a>
  18.     <a href="https://google.com">Google</a>
  19.     <a href="https://github.com">GitHub</a>
  20.   </body>
  21. </html>
  22. `;
  23. const links = extractLinks(html);
  24. console.log(links);
  25. // 输出: ["https://example.com", "https://google.com", "https://github.com"]
复制代码

案例3:文本替换
  1. // 将文本中的URL转换为链接
  2. function urlToLink(text) {
  3.   const urlPattern = /(https?:\/\/[^\s]+)/g;
  4.   return text.replace(urlPattern, '<a href="$1">$1</a>');
  5. }
  6. // 使用示例
  7. const text = 'Visit https://example.com or https://google.com for more information.';
  8. const linkedText = urlToLink(text);
  9. console.log(linkedText);
  10. // 输出: "Visit <a href="https://example.com">https://example.com</a> or <a href="https://google.com">https://google.com</a> for more information."
复制代码

案例4:数据清洗
  1. // 清理用户输入,移除特殊字符和多余空格
  2. function cleanInput(input) {
  3.   // 移除首尾空格
  4.   let cleaned = input.trim();
  5.   // 将多个连续空格替换为一个空格
  6.   cleaned = cleaned.replace(/\s+/g, ' ');
  7.   // 移除特殊字符,只保留字母、数字、中文和基本标点
  8.   cleaned = cleaned.replace(/[^\w\u4e00-\u9fa5\s.,!?;:()'"-]/g, '');
  9.   return cleaned;
  10. }
  11. // 使用示例
  12. const input = '  Hello, 世界!  This is a test...  ';
  13. const cleaned = cleanInput(input);
  14. console.log(cleaned);
  15. // 输出: "Hello, 世界! This is a test..."
复制代码

案例5:日志分析
  1. // 解析Apache访问日志
  2. function parseApacheLog(logLine) {
  3.   const logPattern = /^(\S+) \S+ \S+ \[([\w:/]+\s[+\-]\d{4})\] "(\S+) (\S+) (\S+)" (\d{3}) (\d+|-) "([^"]*)" "([^"]*)"/;
  4.   const match = logPattern.exec(logLine);
  5.   
  6.   if (match) {
  7.     return {
  8.       ip: match[1],
  9.       timestamp: match[2],
  10.       method: match[3],
  11.       url: match[4],
  12.       protocol: match[5],
  13.       status: match[6],
  14.       size: match[7],
  15.       referer: match[8],
  16.       userAgent: match[9]
  17.     };
  18.   }
  19.   
  20.   return null;
  21. }
  22. // 使用示例
  23. const logLine = '127.0.0.1 - - [25/Dec/2023:10:00:00 +0000] "GET /index.html HTTP/1.1" 200 1234 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"';
  24. const logData = parseApacheLog(logLine);
  25. console.log(logData);
  26. // 输出: {
  27. //   ip: "127.0.0.1",
  28. //   timestamp: "25/Dec/2023:10:00:00 +0000",
  29. //   method: "GET",
  30. //   url: "/index.html",
  31. //   protocol: "HTTP/1.1",
  32. //   status: "200",
  33. //   size: "1234",
  34. //   referer: "-",
  35. //   userAgent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
  36. // }
复制代码

总结与进阶学习资源

正则表达式是JavaScript中处理文本的强大工具,掌握它可以大大提升代码效率和开发体验。本文从基础概念讲起,逐步深入到高级技巧和常见问题解决方案,帮助读者全面掌握JavaScript正则表达式。

进阶学习资源

1. MDN - Regular expressions:MDN上的正则表达式指南,详细介绍了JavaScript中的正则表达式。
2. Regex101:在线正则表达式测试工具,支持多种语言,提供详细的解释和调试功能。
3. RegExr:另一个在线正则表达式测试工具,提供丰富的参考资料和示例。
4. Mastering Regular Expressions:正则表达式经典书籍,深入介绍了正则表达式的原理和应用。
5. JavaScript RegExp Reference:W3Schools上的JavaScript RegExp参考手册,提供了快速查询的语法和方法列表。

最佳实践

1. 保持简单:尽量使用简单明了的正则表达式,避免过度复杂的模式。
2. 添加注释:对于复杂的正则表达式,添加注释解释其工作原理。
3. 测试边界情况:测试各种边界情况,确保正则表达式在各种情况下都能正确工作。
4. 考虑性能:避免使用可能导致大量回溯的正则表达式,特别是在处理大量文本时。
5. 使用适当的工具:使用在线工具测试和调试正则表达式,提高开发效率。

通过不断学习和实践,你将能够熟练掌握JavaScript正则表达式,并在实际项目中灵活应用,提升代码效率和开发体验。
「七転び八起き(ななころびやおき)」
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则