🔤 基本语法 >>>
.:匹配任意单个字符(除换行符)
\d:匹配数字 [0-9]
\D:匹配非数字 [^0-9]
\w:匹配字母、数字、下划线 [a-zA-Z0-9_]
\W:匹配非字母、数字、下划线 [^a-zA-Z0-9_]
\s:匹配空白字符(空格、制表符、换行符等)
\S:匹配非空白字符
[abc]:匹配方括号内任意一个字符
[^abc]:匹配除方括号内字符外的任意字符
[a-z]:匹配小写字母范围
[A-Z]:匹配大写字母范围
[0-9]:匹配数字范围
// 匹配一个或多个数字
const regex = /\d+/;
const str = "123abc";
// 测试是否匹配
console.log(regex.test(str));
// 获取匹配结果
console.log(str.match(regex));
*:匹配前面的字符 0 次或多次
+:匹配前面的字符 1 次或多次
?:匹配前面的字符 0 次或 1 次(可选)
{n}:匹配前面的字符恰好 n 次
{n,}:匹配前面的字符至少 n 次
{n,m}:匹配前面的字符 n 到 m 次
*?:非贪婪匹配,尽可能少匹配
+?:非贪婪匹配,尽可能少匹配
??:非贪婪匹配,尽可能少匹配
{n,m}?:非贪婪匹配,尽可能少匹配
// 贪婪匹配 vs 非贪婪匹配
const greedy = /a.*b/;
const lazy = /a.*?b/;
const str = "a123b456b";
// 贪婪匹配:匹配尽可能多的字符
console.log(str.match(greedy));
// 非贪婪匹配:匹配尽可能少的字符
console.log(str.match(lazy));
^:匹配字符串开头
$:匹配字符串结尾
\b:匹配单词边界
\B:匹配非单词边界
// 匹配整个字符串
const regex = /^\d+$/;
// 只包含数字,匹配成功
console.log(regex.test("123"));
// 包含非数字字符,匹配失败
console.log(regex.test("123abc"));
// 匹配单词边界
const wordRegex = /\bcat\b/;
// 作为单独单词,匹配成功
console.log(wordRegex.test("cat"));
// 作为单词前缀,匹配失败
console.log(wordRegex.test("category"));
📦 分组与引用 >>>
(abc):捕获组,匹配 abc 并记住匹配项
(?:abc):非捕获组,匹配 abc 但不记住匹配项
\1, \2, ...:反向引用,引用之前的捕获组
(?abc):命名捕获组
\k:命名反向引用
// 捕获组与反向引用
const regex = /(\w+)\s+\1/;
// 相同单词重复,匹配成功
console.log(regex.test("hello hello"));
// 不同单词,匹配失败
console.log(regex.test("hello world"));
// 命名捕获组
const namedRegex = /(?\d{4})-(?\d{2})-(?\d{2})/;
const match = "2023-12-25".match(namedRegex);
// 获取命名捕获组结果
console.log(match.groups);
(?=abc):正向先行断言,匹配后面是 abc 的位置
(?!abc):负向先行断言,匹配后面不是 abc 的位置
(?<=abc):正向后行断言,匹配前面是 abc 的位置
(?:负向后行断言,匹配前面不是 abc 的位置
// 正向先行断言:匹配后面是 "@gmail.com" 的邮箱
const gmailRegex = /\w+(?=@gmail\.com)/;
console.log("user@gmail.com".match(gmailRegex));
// 负向先行断言:匹配后面不是 "@gmail.com" 的邮箱
const nonGmailRegex = /\w+(?!@gmail\.com)/;
console.log("user@outlook.com".match(nonGmailRegex));
// 正向后行断言:匹配前面是 "https://" 的域名
const domainRegex = /(?<=https:\/\/)\w+\.\w+/;
console.log("https://example.com".match(domainRegex));
g:全局匹配,找到所有匹配项
i:忽略大小写
m:多行匹配,使 ^ 和 $ 匹配每行的开头和结尾
s:dotAll 模式,使 . 匹配包括换行符在内的所有字符
u:Unicode 模式,正确处理 Unicode 字符
y:粘性匹配,仅从目标字符串的当前位置开始匹配
// 全局匹配所有数字
const regex = /\d+/g;
const str = "123abc456def789";
// 全局匹配找到所有数字
console.log(str.match(regex));
// 忽略大小写
const caseInsensitive = /hello/i;
// 忽略大小写,匹配成功
console.log(caseInsensitive.test("Hello"));
// 忽略大小写,匹配成功
console.log(caseInsensitive.test("HELLO"));
// 多行匹配
const multiLine = /^\d+/gm;
const multiStr = "123\n456\n789";
// 多行匹配,匹配每行开头的数字
console.log(multiStr.match(multiLine));
📚 JavaScript 正则方法 >>>
RegExp 对象方法
test():测试字符串是否匹配,返回布尔值
exec():执行匹配,返回匹配结果数组或 null
String 对象方法
match():获取匹配结果数组
matchAll():获取所有匹配结果的迭代器
search():查找匹配位置,返回索引或 -1
replace():替换匹配项,返回新字符串
split():根据匹配分割字符串,返回数组
// RegExp.test()
const regex = /\d+/;
// 测试字符串是否匹配
console.log(regex.test("123"));
// RegExp.exec()
const execRegex = /(\w+)=\w+/;
const str = "name=John&age=30";
// 执行匹配并返回捕获组
console.log(execRegex.exec(str));
// String.replace()
const replaceRegex = /\d+/g;
const replaceStr = "I have 3 apples and 5 oranges";
// 替换所有数字为 "many"
console.log(replaceStr.replace(replaceRegex, "many"));
// String.split()
const splitRegex = /\s+/;
const splitStr = "Hello world\n JavaScript";
// 根据空白字符分割字符串
console.log(splitStr.split(splitRegex));
🚀 高级技巧 >>>
密码强度验证
// 至少8个字符,包含大小写字母、数字和特殊字符
const passwordRegex = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$/;
// 强密码,验证通过
console.log(passwordRegex.test("Password123!"));
// 弱密码,验证失败
console.log(passwordRegex.test("weakpass"));
// 邮箱验证
const emailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
// 有效邮箱,验证通过
console.log(emailRegex.test("user@example.com"));
// 无效邮箱,验证失败
console.log(emailRegex.test("invalid-email"));
// URL验证
const urlRegex = /^(https?:\/\/)?([\da-z.-]+)\.([a-z.]{2,6})([/\w .-]*)*\/?$/;
// HTTPS URL,验证通过
console.log(urlRegex.test("https://example.com"));
// HTTP localhost URL,验证通过
console.log(urlRegex.test("http://localhost:3000"));
复杂替换
// 驼峰命名转短横线命名
const camelToKebab = (str) => str.replace(/[A-Z]/g, (match) => `-${match.toLowerCase()}`);
console.log(camelToKebab("helloWorld"));
// 短横线命名转驼峰命名
const kebabToCamel = (str) => str.replace(/-([a-z])/g, (match, p1) => p1.toUpperCase());
console.log(kebabToCamel("hello-world"));
// 首字母大写
const capitalize = (str) => str.replace(/\b\w/g, (match) => match.toUpperCase());
console.log(capitalize("hello world javascript"));
⚠️ 常见问题与注意事项
- 正则表达式中的特殊字符需要转义:
\^$.*+?()[]{}|
- 使用
RegExp.prototype.exec() 时,全局匹配需要循环调用
- 避免过度使用复杂正则表达式,考虑可读性和性能
- 注意贪婪匹配与非贪婪匹配的区别
- 使用命名捕获组可以提高代码可读性
- 正则表达式不是万能的,某些情况下使用字符串方法更高效
// 转义特殊字符
const escapedRegex = /\.\*\+/;
// 匹配特殊字符组合 ".*+"
console.log(escapedRegex.test(".*+"));
// 全局匹配循环
const globalRegex = /\w+/g;
const globalStr = "hello world javascript";
let match;
// 循环获取所有匹配结果
while ((match = globalRegex.exec(globalStr)) !== null) {
console.log(`匹配到: ${match[0]}, 索引: ${match.index}`);
}
🛠️ 正则表达式工具 >>>
- Regex101:在线正则表达式测试工具,支持多种语言
- RegExr:可视化正则表达式编辑器,包含示例和参考
- JavaScript RegExp Tester:专为 JavaScript 设计的测试工具
- Debuggex:正则表达式可视化工具,帮助理解复杂正则
使用在线工具可以帮助你调试和优化正则表达式,提高开发效率。