以下是老曹关于 JavaScript 原生 RegExp
对象(正则表达式) 的 20 道常见面试题总结,适用于前端开发岗位的技术面试。每道题都包含详细解释和代码示例,大家可以随时翻出来查阅背诵和练习!
1. 如何创建一个正则表达式?
问题: 使用 JavaScript 创建正则表达式的两种方式?
答案:
- 使用字面量形式。
- 使用
new RegExp()
构造函数。
// 字面量
const regex1 = /hello/;
// 构造函数
const regex2 = new RegExp("hello");
console.log(regex1.test("hello world")); // 输出: true
console.log(regex2.test("hello world")); // 输出: true
2. 正则表达式中的 g
、i
、m
标志分别代表什么含义?
问题: 解释 /\w+/gi
中的 g
和 i
的作用。
答案:
g
:全局匹配(查找所有匹配项,而不是找到第一个就停止)。i
:忽略大小写。m
:多行模式(影响^
和$
的行为)。
const str = "Hello hello HELLO";
const regex = /hello/gi;
console.log(str.match(regex)); // 输出: ["Hello", "hello", "HELLO"]
3. 如何测试字符串是否匹配正则表达式?
问题: 使用什么方法可以判断字符串是否满足某个正则表达式?
答案:
使用 test()
方法。
const regex = /^[A-Z][a-z]+$/;
console.log(regex.test("John")); // 输出: true
console.log(regex.test("john")); // 输出: false
4. match()
和 exec()
的区别是什么?
问题: 写出 match()
与 exec()
在全局匹配时的不同表现。
答案:
match()
返回所有匹配项组成的数组。exec()
返回每次匹配的结果,并可遍历所有结果。
const str = "abc123def456";
const regex = /\d+/g;
console.log(str.match(regex)); // 输出: ["123", "456"]
let match;
while ((match = regex.exec(str)) !== null) {
console.log(match); // 输出: ["123", index: 3, ...], ["456", index: 6, ...]
}
5. 如何提取字符串中符合正则的部分?
问题: 提取字符串中的所有数字部分。
答案:
使用带有分组的正则表达式配合 match()
或 exec()
。
const str = "Phone: 123-456-7890";
const regex = /(\d{3})-(\d{3})-(\d{4})/;
const parts = str.match(regex);
console.log(parts); // 输出: ["123-456-7890", "123", "456", "7890"]
6. 如何替换字符串中符合正则的部分?
问题: 将字符串中的所有连续空格替换为单个空格。
答案:
使用 replace()
方法配合正则表达式。
const str = "This is a test.";
const result = str.replace(/\s+/g, " ");
console.log(result); // 输出: "This is a test."
7. 如何验证一个字符串是否是合法的邮箱格式?
问题: 编写一个正则表达式校验邮箱格式。
答案:
使用常见的邮箱正则表达式。
function isValidEmail(email) {
const regex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
return regex.test(email);
}
console.log(isValidEmail("user@example.com")); // 输出: true
console.log(isValidEmail("invalid-email@")); // 输出: false
8. 如何验证手机号码格式?
问题: 匹配中国大陆手机号(11位数字,以1开头)。
答案:
使用正则表达式进行简单验证。
function isValidPhone(phone) {
const regex = /^1\d{10}$/;
return regex.test(phone);
}
console.log(isValidPhone("13812345678")); // 输出: true
console.log(isValidPhone("123456789")); // 输出: false
9. 如何提取 URL 中的参数?
问题: 使用正则从 URL 中提取 id=123
的值。
答案:
使用捕获组获取参数值。
function getQueryParam(url, key) {
const regex = new RegExp(`[?&]${key}=([^&]*)`);
const match = url.match(regex);
return match ? decodeURIComponent(match[1]) : null;
}
const url = "https://example.com?id=123&name=Tom";
console.log(getQueryParam(url, "id")); // 输出: "123"
console.log(getQueryParam(url, "name")); // 输出: "Tom"
10. 如何去除字符串两端的空白字符?
问题: 实现类似 trim()
的功能。
答案:
使用正则表达式去除前后空白。
function myTrim(str) {
return str.replace(/^\s+|\s+$/g, '');
}
console.log(myTrim(" Hello World ")); // 输出: "Hello World"
11. 正则中的 ^
和 $
分别表示什么?
问题: 写出 /^abc$/
可以匹配哪些字符串。
答案:
^
表示字符串开始。$
表示字符串结束。- 所以上述正则只匹配
"abc"
。
console.log(/^abc$/.test("abc")); // 输出: true
console.log(/^abc$/.test("abcd")); // 输出: false
12. 正则中的 []
和 ()
的区别是什么?
问题: 写出 /[aeiou]/
和 /(abc)/
的不同作用。
答案:
[]
表示任意一个字符在集合中。()
表示一个整体,用于分组或捕获。
console.log(/[aeiou]/.test("apple")); // 输出: true(匹配 'a')
console.log(/(abc)/.test("abc")); // 输出: true(匹配整个 abc)
13. 如何使用正则实现字符串的“模糊搜索”?
问题: 模糊匹配 “cat” 是否出现在字符串中(不区分大小写)。
答案:
使用 i
标志进行忽略大小写的匹配。
const regex = /cat/i;
console.log(regex.test("CAT")); // 输出: true
console.log(regex.test("cAt")); // 输出: true
14. 如何限制输入框只能输入数字?
问题: 使用正则过滤非数字字符。
答案:
使用正则表达式结合 replace()
。
function onlyNumbers(input) {
return input.replace(/[^0-9]/g, '');
}
console.log(onlyNumbers("abc123xyz")); // 输出: "123"
15. 正则中的 ?=
和 ?!
是什么意思?
问题: 写出 /(?=.*[A-Z])/
的作用。
答案:
?=
:正向先行断言(匹配但不消耗字符)。?!
:负向先行断言。
// 确保字符串中至少有一个大写字母
const regex = /(?=.*[A-Z])/;
console.log(regex.test("Password")); // 输出: true
console.log(regex.test("password")); // 输出: false
16. 如何用正则验证密码强度(至少包含大小写字母和数字)?
问题: 密码必须同时包含大小写字母和数字。
答案:
使用多个正向先行断言组合。
function isValidPassword(password) {
const regex = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).+$/;
return regex.test(password);
}
console.log(isValidPassword("StrongPass123")); // 输出: true
console.log(isValidPassword("weakpass")); // 输出: false
17. 如何用正则匹配 HTML 标签内容?
问题: 提取 <p>...</p>
中的内容。
答案:
使用非贪婪匹配。
const html = "<p>Hello <b>World</b></p>";
const regex = /<p>(.*?)<\/p>/;
const match = html.match(regex);
console.log(match[1]); // 输出: "Hello <b>World</b>"
18. 如何防止正则表达式中的“贪婪匹配”?
问题: 默认情况下正则为何会匹配到多余的内容?
答案:
默认是贪婪匹配,添加 ?
转为非贪婪。
const str = "start middle end";
const greedyRegex = /start.*end/;
const nonGreedyRegex = /start.*?end/;
console.log(str.match(greedyRegex)[0]); // 输出: "start middle end"
console.log(str.match(nonGreedyRegex)[0]); // 输出: "start middle end"
19. 如何动态生成正则表达式?
问题: 根据用户输入构建正则。
答案:
使用 new RegExp()
并注意转义特殊字符。
function createSearchRegex(term) {
const escapedTerm = term.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
return new RegExp(escapedTerm, 'gi');
}
const regex = createSearchRegex("hello.");
console.log(regex.test("hello.world")); // 输出: true
20. 如何判断浏览器是否支持某个正则特性?
问题: 判断当前环境是否支持 lookbehind
(如 (?<=...)
)。
答案:
使用 try...catch
来检测。
function supportsLookbehind() {
try {
new RegExp("(?<=.)");
return true;
} catch (e) {
return false;
}
}
console.log(supportsLookbehind()); // 输出: true 或 false(取决于浏览器)
📋 总结表格
编号 | 题目描述 | 知识点 | 示例代码 | 常见考察点 |
---|---|---|---|---|
1 | 创建正则的方式 | 字面量 vs 构造函数 | new RegExp("abc") | 基础语法 |
2 | 标志符 g/i/m 的含义 | 全局/忽略大小写/多行 | /hello/gi | 匹配控制 |
3 | 测试是否匹配 | test() 方法 | regex.test(str) | 条件判断 |
4 | match() vs exec() | 获取匹配结果 | str.match(regex) | 多次匹配 |
5 | 提取分组内容 | 捕获组 | str.match(/(\d+)/) | 数据提取 |
6 | 替换字符串 | replace() | str.replace(/\s+/g, ' ') | 字符处理 |
7 | 邮箱格式验证 | 综合应用 | /^[^\s@]+@[^\s@]+\.\S+$/ | 表单验证 |
8 | 手机号码验证 | 数字匹配 | /^1\d{10}$/ | 输入控制 |
9 | 提取 URL 参数 | 分组提取 | new RegExp("[?&]" + key + "=([^&]*)") | 字符串解析 |
10 | 自定义 trim 函数 | 去除空格 | `str.replace(/^\s+ | \s+$/g, ‘’)` |
11 | ^ 和 $ 的作用 | 锚点 | /^abc$/ | 完全匹配 |
12 | [] vs () 的区别 | 字符集 vs 分组 | [aeiou] vs (abc) | 正则结构 |
13 | 模糊搜索 | 忽略大小写 | /cat/i | 查询优化 |
14 | 过滤非数字字符 | 排除非数字 | /[^0-9]/g | 输入清理 |
15 | 正向/负向断言 | 条件匹配 | (?=.*[A-Z]) | 复杂条件 |
16 | 密码强度验证 | 多条件组合 | (?=.*[a-z])(?=.*[A-Z])(?=.*\d) | 安全性检查 |
17 | 提取 HTML 标签内容 | 非贪婪匹配 | /<p>(.*?)<\/p>/ | 字符串解析 |
18 | 控制贪婪匹配 | 非贪婪符号 | .*? | 精确匹配 |
19 | 动态生成正则 | 构造函数 | new RegExp(...) | 用户输入 |
20 | 检测正则特性支持 | 异常处理 | try { new RegExp(...) } | 浏览器兼容 |