正则表达式用于匹配字符串中的模式。
// 使用斜杠包裹
const regex = /东巴文/;
const regex2 = /东巴文/gi; // 带修饰符
// 使用构造函数
const regex = new RegExp("东巴文");
const regex2 = new RegExp("东巴文", "gi");
// 动态创建
const pattern = "东巴文";
const regex3 = new RegExp(pattern, "g");
// 字面量:静态模式
const regex1 = /pattern/;
// 构造函数:动态模式
const userInput = "动态内容";
const regex2 = new RegExp(userInput);
// 字面量不需要转义
const regex3 = /\d+/;
const regex4 = new RegExp("\\d+"); // 需要双重转义
| 字符 | 说明 | 示例 |
|---|---|---|
| . | 任意字符(除换行) | /a.c/ 匹配 "abc" |
| \d | 数字 | /\d/ 匹配 "5" |
| \D | 非数字 | /\D/ 匹配 "a" |
| \w | 单词字符 | /\w/ 匹配 "a"、"1" |
| \W | 非单词字符 | /\W/ 匹配 "@" |
| \s | 空白字符 | /\s/ 匹配 " " |
| \S | 非空白字符 | /\S/ 匹配 "a" |
| \b | 单词边界 | /\bword\b/ |
| \B | 非单词边界 | /\Bword\B/ |
// 需要转义的特殊字符
// ^ $ . * + ? { } [ ] \ | ( )
const regex1 = /\./; // 匹配点号
const regex2 = /\$/; // 匹配美元符号
const regex3 = /\*/; // 匹配星号
// [abc]:匹配a、b或c
const regex1 = /[abc]/;
console.log(regex1.test("a")); // true
console.log(regex1.test("d")); // false
// [^abc]:匹配除a、b、c之外的字符
const regex2 = /[^abc]/;
console.log(regex2.test("a")); // false
console.log(regex2.test("d")); // true
// [a-z]:匹配a到z
const regex3 = /[a-z]/;
console.log(regex3.test("m")); // true
// [0-9]:匹配0到9
const regex4 = /[0-9]/;
console.log(regex4.test("5")); // true
// [a-zA-Z0-9]:匹配字母和数字
const regex5 = /[a-zA-Z0-9]/;
// 中文
const chinese = /[\u4e00-\u9fa5]/;
console.log(chinese.test("东")); // true
// 手机号
const phone = /^1[3-9]\d{9}$/;
// 邮箱
const email = /^[\w.-]+@[\w.-]+\.\w+$/;
// 身份证号
const idCard = /^\d{17}[\dXx]$/;
量词指定匹配的次数。
| 量词 | 说明 | 示例 |
|---|---|---|
| * | 0次或多次 | /a*/ 匹配 ""、"a"、"aaa" |
| + | 1次或多次 | /a+/ 匹配 "a"、"aaa" |
| ? | 0次或1次 | /a?/ 匹配 ""、"a" |
| {n} | 恰好n次 | /a{3}/ 匹配 "aaa" |
| {n,} | 至少n次 | /a{2,}/ 匹配 "aa"、"aaa" |
| {n,m} | n到m次 | /a{2,4}/ 匹配 "aa"、"aaa"、"aaaa" |
const str = "<div>内容</div>";
// 贪婪匹配(默认)
const greedy = /<.*>/;
console.log(str.match(greedy)); // ["<div>内容</div>"]
// 非贪婪匹配(加?)
const lazy = /<.*?>/;
console.log(str.match(lazy)); // ["<div>"]
// 匹配手机号
const phone = /^1[3-9]\d{9}$/;
// 匹配QQ号(5-11位)
const qq = /^\d{5,11}$/;
// 匹配邮政编码
const postal = /^\d{6}$/;
// 匹配IP地址
const ip = /^(\d{1,3}\.){3}\d{1,3}$/;
锚点指定匹配的位置。
// ^:字符串开始
const start = /^东巴文/;
console.log(start.test("东巴文学习")); // true
console.log(start.test("学习东巴文")); // false
// $:字符串结束
const end = /东巴文$/;
console.log(end.test("学习东巴文")); // true
console.log(end.test("东巴文学习")); // false
// 完全匹配
const exact = /^东巴文$/;
console.log(exact.test("东巴文")); // true
console.log(exact.test("东巴文学习")); // false
// \b:单词边界
const word = /\bword\b/;
console.log(word.test("word")); // true
console.log(word.test("a word b")); // true
console.log(word.test("password")); // false
// \B:非单词边界
const notWord = /\Bword\B/;
console.log(notWord.test("password")); // true
const str = "第一行\n第二行\n第三行";
// 不使用m修饰符
const regex1 = /^第/g;
console.log(str.match(regex1)); // ["第"]
// 使用m修饰符
const regex2 = /^第/gm;
console.log(str.match(regex2)); // ["第", "第", "第"]
分组用于捕获和引用匹配内容。
// 使用括号创建捕获组
const regex = /(\d{4})-(\d{2})-(\d{2})/;
const str = "2024-01-15";
const match = str.match(regex);
console.log(match[0]); // "2024-01-15"(完整匹配)
console.log(match[1]); // "2024"(第一个捕获组)
console.log(match[2]); // "01"(第二个捕获组)
console.log(match[3]); // "15"(第三个捕获组)
// 使用?<name>命名
const regex = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/;
const str = "2024-01-15";
const match = str.match(regex);
console.log(match.groups.year); // "2024"
console.log(match.groups.month); // "01"
console.log(match.groups.day); // "15"
// 使用(?:)创建非捕获组
const regex = /(?:https?:\/\/)?([\w.-]+)/;
const str = "https://example.com";
const match = str.match(regex);
console.log(match[0]); // "https://example.com"
console.log(match[1]); // "example.com"(协议被非捕获组排除)
// 使用\n引用第n个捕获组
const regex = /(\w)\1/;
console.log(regex.test("aa")); // true(匹配重复字符)
console.log(regex.test("ab")); // false
// 匹配HTML标签
const tag = /<(\w+)>.*<\/\1>/;
console.log(tag.test("<div>内容</div>")); // true
console.log(tag.test("<div>内容</span>")); // false
修饰符改变正则表达式的行为。
| 修饰符 | 说明 | 示例 |
|---|---|---|
| g | 全局匹配 | /a/g 匹配所有"a" |
| i | 忽略大小写 | /a/i 匹配 "A"、"a" |
| m | 多行模式 | /^a/m 匹配每行开头 |
| s | dotAll模式 | /./s 匹配包括换行 |
| u | Unicode模式 | 处理Unicode字符 |
| y | 粘连模式 | 从lastIndex开始匹配 |
// g:全局匹配
const str = "东巴文东巴文";
console.log(str.match(/东巴文/g)); // ["东巴文", "东巴文"]
// i:忽略大小写
console.log(/hello/i.test("HELLO")); // true
// m:多行模式
const multi = `第一行
第二行
第三行`;
console.log(multi.match(/^第/gm)); // ["第", "第", "第"]
// s:dotAll模式
console.log(/a.b/s.test("a\nb")); // true
// u:Unicode模式
console.log(/\u{1F600}/u.test("😀")); // true
// test:检查是否匹配,返回布尔值
const regex = /东巴文/;
console.log(regex.test("学习东巴文")); // true
console.log(regex.test("学习")); // false
// 全局匹配时注意lastIndex
const regex2 = /a/g;
console.log(regex2.test("aaa")); // true
console.log(regex2.lastIndex); // 1
console.log(regex2.test("aaa")); // true
console.log(regex2.lastIndex); // 2
// exec:返回匹配结果数组
const regex = /(\d+)/g;
const str = "a1b2c3";
let match;
while ((match = regex.exec(str)) !== null) {
console.log(`找到: ${match[0]}, 位置: ${match.index}`);
}
// 找到: 1, 位置: 1
// 找到: 2, 位置: 3
// 找到: 3, 位置: 5
const regex = /a/g;
const str = "aaa";
regex.lastIndex = 1; // 从索引1开始匹配
console.log(regex.exec(str)); // ["a", index: 1]
const str = "东巴文2024年01月15日";
// 非全局匹配
console.log(str.match(/\d+/));
// ["2024", index: 3, input: "东巴文2024年01月15日", groups: undefined]
// 全局匹配
console.log(str.match(/\d+/g)); // ["2024", "01", "15"]
// 未匹配返回null
console.log(str.match(/xyz/)); // null
const str = "a1b2c3";
const regex = /([a-z])(\d)/g;
for (const match of str.matchAll(regex)) {
console.log(match);
}
// ["a1", "a", "1", index: 0, ...]
// ["b2", "b", "2", index: 2, ...]
// ["c3", "c", "3", index: 4, ...]
// search:返回第一个匹配的索引
const str = "东巴文学习";
console.log(str.search(/学习/)); // 3
console.log(str.search(/不存在/)); // -1
const str = "东巴文2024";
// 替换第一个匹配
console.log(str.replace(/\d/, "X")); // "东巴文X024"
// 全局替换
console.log(str.replace(/\d/g, "X")); // "东巴文XXXX"
// 使用捕获组
const date = "2024-01-15";
console.log(date.replace(/(\d{4})-(\d{2})-(\d{2})/, "$3/$2/$1"));
// "15/01/2024"
// 使用回调函数
const result = str.replace(/\d/g, (match, offset) => {
return `[${match}]`;
});
console.log(result); // "东巴文[2][0][2][4]"
const str = "a1b2c3";
// 使用正则分割
console.log(str.split(/\d/)); // ["a", "b", "c", ""]
// 验证手机号
function validatePhone(phone) {
return /^1[3-9]\d{9}$/.test(phone);
}
// 验证邮箱
function validateEmail(email) {
return /^[\w.-]+@[\w.-]+\.\w+$/.test(email);
}
// 验证密码(8-20位,包含字母和数字)
function validatePassword(password) {
return /^(?=.*[a-zA-Z])(?=.*\d)[a-zA-Z\d]{8,20}$/.test(password);
}
// 验证URL
function validateURL(url) {
return /^https?:\/\/[\w.-]+(:\d+)?(\/[\w./-]*)?$/.test(url);
}
// 提取URL参数
function getQueryParams(url) {
const params = {};
const regex = /[?&]([^=&]+)=([^&]*)/g;
let match;
while ((match = regex.exec(url)) !== null) {
params[match[1]] = decodeURIComponent(match[2]);
}
return params;
}
console.log(getQueryParams("https://example.com?name=东巴文&age=1"));
// { name: "东巴文", age: "1" }
// 去除HTML标签
function stripHTML(html) {
return html.replace(/<[^>]+>/g, "");
}
// 千分位格式化
function formatNumber(num) {
return num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}
console.log(formatNumber(1234567)); // "1,234,567"
// 手机号脱敏
function maskPhone(phone) {
return phone.replace(/(\d{3})\d{4}(\d{4})/, "$1****$2");
}
console.log(maskPhone("13812345678")); // "138****5678"
掌握了正则表达式后,让我们继续学习:
东巴文(db-w.cn) - 让编程学习更简单
🔍 东巴文寄语:正则表达式是处理字符串的强大工具,虽然语法复杂,但掌握后能极大提高文本处理效率。从简单的匹配开始,逐步掌握高级用法。在 db-w.cn,我们帮你攻克正则表达式!