正则表达式常用方法

JavaScript 正则表达式的方法使用与实际场景

问题

JavaScript 中正则表达式有哪些常用方法?各自适用什么场景?

解答

RegExp 方法

test() - 判断是否匹配

const reg = /\d+/;

reg.test('abc123');  // true
reg.test('abc');     // false

// 场景:表单验证
const emailReg = /^[\w.-]+@[\w.-]+\.\w+$/;
emailReg.test('test@example.com');  // true

exec() - 获取匹配详情

const reg = /(\d{4})-(\d{2})-(\d{2})/;
const result = reg.exec('日期:2024-01-15');

console.log(result[0]);  // '2024-01-15' 完整匹配
console.log(result[1]);  // '2024' 第一个捕获组
console.log(result[2]);  // '01' 第二个捕获组
console.log(result.index);  // 3 匹配位置

// 配合 g 标志循环匹配
const gReg = /\d+/g;
const str = 'a1b22c333';
let match;
while ((match = gReg.exec(str)) !== null) {
  console.log(match[0], match.index);
  // '1' 1
  // '22' 3
  // '333' 6
}

String 方法

match() - 返回匹配结果

const str = 'a1b22c333';

// 不带 g:返回详细信息(同 exec)
str.match(/\d+/);  // ['1', index: 1, ...]

// 带 g:返回所有匹配项
str.match(/\d+/g);  // ['1', '22', '333']

// 无匹配返回 null
str.match(/x/);  // null

matchAll() - 返回所有匹配的迭代器

const str = '2024-01-15 和 2024-02-20';
const reg = /(\d{4})-(\d{2})-(\d{2})/g;

// 返回迭代器,每项包含捕获组信息
for (const match of str.matchAll(reg)) {
  console.log(match[0], match[1], match[2], match[3]);
  // '2024-01-15' '2024' '01' '15'
  // '2024-02-20' '2024' '02' '20'
}

// 转数组
const matches = [...str.matchAll(reg)];

search() - 返回匹配位置

const str = 'hello world';

str.search(/world/);  // 6
str.search(/x/);      // -1(未找到)

// 类似 indexOf,但支持正则

replace() / replaceAll() - 替换

const str = 'hello world';

// replace:替换第一个(或用 g 替换全部)
str.replace(/o/, '0');   // 'hell0 world'
str.replace(/o/g, '0');  // 'hell0 w0rld'

// replaceAll:替换全部(正则必须带 g)
str.replaceAll(/o/g, '0');  // 'hell0 w0rld'

// 使用捕获组
'2024-01-15'.replace(/(\d{4})-(\d{2})-(\d{2})/, '$2/$3/$1');
// '01/15/2024'

// 使用函数
'a1b2'.replace(/\d/g, (match, index) => {
  return match * 2;
});  // 'a2b4'

split() - 分割字符串

// 按正则分割
'a1b22c333d'.split(/\d+/);  // ['a', 'b', 'c', 'd']

// 保留分隔符(使用捕获组)
'a1b22c'.split(/(\d+)/);  // ['a', '1', 'b', '22', 'c']

实际场景示例

// 1. 手机号验证
const phoneReg = /^1[3-9]\d{9}$/;
phoneReg.test('13812345678');  // true

// 2. 提取 URL 参数
function getParams(url) {
  const params = {};
  const reg = /([^?&=]+)=([^&]*)/g;
  for (const [, key, value] of url.matchAll(reg)) {
    params[key] = decodeURIComponent(value);
  }
  return params;
}
getParams('?name=tom&age=18');  // { name: 'tom', age: '18' }

// 3. 千分位格式化
function formatNumber(num) {
  return String(num).replace(/\B(?=(\d{3})+$)/g, ',');
}
formatNumber(1234567);  // '1,234,567'

// 4. 去除 HTML 标签
function stripTags(html) {
  return html.replace(/<[^>]+>/g, '');
}
stripTags('<p>hello</p>');  // 'hello'

// 5. 驼峰转换
function toCamelCase(str) {
  return str.replace(/-([a-z])/g, (_, c) => c.toUpperCase());
}
toCamelCase('background-color');  // 'backgroundColor'

关键点

  • test() 用于验证,返回布尔值
  • exec()matchAll() 获取捕获组详情
  • match() 带 g 返回数组,不带 g 返回详情
  • replace() 第二个参数可以是函数,实现复杂替换
  • 注意 exec() 配合 g 标志时会记住 lastIndex,需循环调用