Content Table

JS 的正则表达式

JS 中可以用下面 3 种方式使用正则表达式获取数据:

  • RegExp.exec()
  • String.match()
  • String.replace(): 这个用法比较奇葩,但是我喜欢

下面就简单介绍下每一个的用法。

RegExp.exec()

提示: RegExp.exec() 需要使用循环获取所有匹配的值,能够获取捕获组的值,但是正则表达式必须使用 /g,否则会死循环。

1
2
3
4
5
6
7
8
9
10
var str = "task-1.host_ip + task-2.host3ip + global.port";
var reg = /task-(\d+)\.(\w+)|global\.(\w+)/g;

var record;

// 每次循环得到一个匹配的值
while ((record = reg.exec(str)) !== null) {
// record 为查找到的数据的数组,record[1] 为捕获组 1 的值,record[2] 为捕获组 2 的值
console.log(record[1], record[2], record[3]);
}

输出:

1
2
3
1 host_ip undefined
2 host3ip undefined
undefined undefined port

String.match()

提示: String.match() 一次获取得到所有匹配的数据,但是不能够获组捕获组中的值。

1
2
3
4
var str = "task-1.host_ip + task-2.host3ip + global.port";
var reg = /task-(\d+)\.(\w+)|global\.(\w+)/g;

console.log(str.match(reg));

输出:

1
[ 'task-1.host_ip', 'task-2.host3ip', 'global.port' ]

String.replace()

提示: String.replace() 是用来查找字符串中的内容进行替换的,但是也可以用来获取匹配的内容。每找到一个匹配的内容就调用回调函数一次,喜欢用它的原因是回调函数的参数名可以直接给捕获组的值一一对应,比较直观,缺点是效率差了那么一点。

1
2
3
4
5
6
7
var str = "task-1.host_ip + task-2.host3ip + global.port";
var reg = /task-(\d+)\.(\w+)|global\.(\w+)/g;

// m 匹配的内容,第二个参数为捕获组 1 的值,第三个参数为捕获组 2 的值
str.replace(reg, function(m, taskId, taskArgName, globalArgName) {
console.log(taskId, taskArgName, globalArgName);
});

输出:

1
2
3
1 host_ip undefined
2 host3ip undefined
undefined undefined port

当然 String.replace() 的正宗用法是替换匹配的子串,函数 replace 的回调函数中返回的值用于替换匹配的内容,例如下面的字符串格式化函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/**
* 替换字符串中 {placeholder} 或者 {0}, {1} 等模式部分为参数中传入的字符串
* 使用方法:
* formatString('I can speak {language} since I was {age}', {language: 'Javascript', age: 10})
* formatString('I can speak {0} since I was {1}', 'Javascript', 10)
* 输出都为:
* I can speak Javascript since I was 10
*
* @param {String} str 带有 placeholder 的字符串
* @param {JSON} replacements 用来替换 placeholder 的 JSON 对象 (或者数组)
* @return {String} 返回格式化后的字符串
*/
var formatString = function(str, replacements) {
replacements = (typeof replacements === 'object') ? replacements : Array.prototype.slice.call(arguments, 1);
return str.replace(/\{\{|\}\}|\{(\w+)\}/g, function(m, n) {
if (m === '{{') { return '{'; }
if (m === '}}') { return '}'; }
return replacements[n];
});
};