什么是正则表达式
提供了一种在文本中进行搜索和替换的强大方法的模式。 正则表达式的内容繁杂,主要梳理出三个模块
- 正则表达式的创建和修饰符
- 正则表达式的方法,特别是和字符串方法配合使用的
- 正则表达式的语义 这次主要讲前两部分,下一次总结正则表达式的语义
使用正则表达式
创建正则表达式
创建正则表达式的有两种方法
- /查询条件/修饰符
- new一个RegExp对象的构造函数,函数中第一个参数是查询条件,第二个参数是修饰符
var re=/wh/g;
```var re1=new RegExp('wh','g');
6个修饰符
| 修饰符 | 说明 |
|---|---|
| i | 不区分大小写 |
| g | 搜索时会寻找所有匹配项,没有它,则仅返回第一个匹配项 |
| m | 多行模式 |
| s | 允许.匹配换行符\n,使得.匹配所有字符 |
| u | 开启完整的unicode编码 |
| y | 在源字符串中的指定位置进行搜索 |
正则表达式的方法
正则表达式提供了一种搜索和替换的强大功能
搜索 str.match(regexp)
match具有3种工作模式
- 如果正则表达式具有修饰符g,则返回一个由所有匹配项所构成的数组
let str="We will, we will rock you";
let regexp=/we/gi;
console.log(str.match(regexp));
返回结果:[ 'We', 'we' ]
- 如果没有修饰符g,返回一个数组形式的匹配项,包含详细信息
let str="We will, we will rock you";
let regexp=/we/;
console.log(str.match(regexp));
返回结果: [ 'we', index: 9, input: 'We will, we will rock you', groups: undefined ]
- 如果没有匹配项,返回null
匹配所有项 str.matchAll(regexp)
返回一个包含匹配项的可迭代对象,而不是数组 每个匹配项均以一个包含捕获组的数组形式返回 如果每日没有结果,则返回的是一个空的迭代对象,而不是null 正则表达式内必须带有标识符g
let str = "We will, we we will rock you";
let regexp = /we/g;
let matchAll=str.matchAll(regexp);
console.log(matchAll);
for (let ma of matchAll){
console.log(ma);
}
结果: Object [RegExp String Iterator] {} [ 'we', index: 9, input: 'We will, we we will rock you', groups: undefined ] [ 'we', index: 12, input: 'We will, we we will rock you', groups: undefined ]
替换 str.replace(regexp|str,replacement|func)
使用第二个参数替换str中找到的regexp匹配项。如果regexp带有g修饰符,则替换所有匹配项目,否则只替换第一个
let str="We will, we will rock you";
let regexp=/we/i;
console.log(str.replace(regexp,"I"));
结果:I will, we will rock you
第二个参数是字符串replacement。我们可以在其中使用特殊的字符组合来对匹配项进行插入
console.log("I love HTML".replace(/HTML/, "$& and JavaScript"));
let str = "John Smith";
// 交换名字和姓氏
console.log(str.replace(/(john) (smith)/i, '$2, $1')) // Smith, John
| 符号 | 在替换字符串中的行为 | 实例 |
|---|---|---|
| $& | 插入整个匹配项 | I love HTML and JavaScript |
| $` | 插入匹配项之前的字符串部分 | I love I love and JavaScript |
| $' | 插入匹配项之后的字符串部分 | |
| $n | 如果 n 是一个 1-2 位的数字,则插入第 n 个分组的内容 | |
| $ | 插入带有给定 name 的括号内的内容 | I love $ and JavaScript |
| $$ | 插入字符串$ |
第二个参数还可以是个函数,每次匹配都会调用这个函数。并且将返回的值作为替换字符串插入 func(match,p1,p2,...,pn,offset,input,groups) match--匹配项 p1,p2,...,pn——捕获组的内容 offset——匹配项的位置 input——源字符串 groups——具有命名的捕获组对象 如果正则表达式没有相对,则只有三个参数:func(match,offset,input)
将所有匹配项大写
let str = "html and css";
let result = str.replace(/html|css/gi, str => str.toUpperCase());
console.log(result); // HTML and CSS
将每个匹配项替换成其在字符串中的位置
console.log("Ho-Ho-Ho".replace(/Ho/gi, (match, offset) => offset));//0-3-6
捕获组的内容
let str = "John Smith ";
let result = str.replace(
/(\w+) (\w+)/,
(match, name, surname) => `${surname},${name}`
);
console.log(result);//Smith,John
可以使用...rest参数
let str = "John Smith Ronaldo";
result = str.replace(
/(\w+) (\w+)/,
(...matche) => {console.log(matche);return`${matche[2]},${matche[1]}`}
);
console.log(result);
匹配项matche内容 [ 'John Smith', 'John', 'Smith', 0, 'John Smith Ronaldo' ] result结果:Smith,John Ronaldo 命名组
let str = "John Smith Ronaldo";
result = str.replace(/(?<name>\w+) (?<surname>\w+)/, (...match) => {
//从数组中删除最后一个元素的值
console.log(match);
let groups = match.pop();
return `${groups.surname}, ${groups.name}`;
});
console.log(result); // Smith, John Ronaldo
matche匹配内容 [ 'John Smith', 'John', 'Smith', 0, 'John Smith Ronaldo', [Object: null prototype] { name: 'John', surname: 'Smith' } ]
测试 regexp.test(str)
如果有匹配项返回true,否则返回false
let str="We will, we will rock you";
let regexp=/we/i;
console.log(regexp.test(str));//true
分割 str.split(regexp/substr,limit)
使用正则表达式或子字符串作为分隔符来分割字符串
console.log('12-34-56'.split('-'));
console.log('12, 34, 56'.split(/,\s*/));
结果: [ '12', '34', '56' ] [ '12', '34', '56' ]
查找 str.search(regexp)
返回第一个匹配项的位置,如果没找到,则返回-1
let str = "A drop of ink may make a million think";
console.log( str.search( /ink/i ) ); // 10(第一个匹配位置)
regexp.exec(str)
返回字符串中那个regexp的匹配项,它是在正则表达式中调用的 它的行为取决于有没有g 如果没有修饰符g,则返回第一个匹配项 如果有修饰符g ,那么
- 调用regexp.exec会返回第一个匹配项,并将紧随其后的位置保存在regexp.lastIndex中
- 下一次这样的调用会从位置regexp.lastIndex开始搜索,返回下一个匹配项,并将其后的位置保存在regexp.lastIndex中
- 以此类推
- 如果没有匹配项,则返回null,并将regexp.lastIndex重置为0 因此,重复调用会一个接一个地返回所有匹配项,使用属性regexp.lastIndex来跟踪当前搜索位置
let str = 'Hello, world!';
let regexp = /\w+/g; // 没有修饰符 "g",lastIndex 属性会被忽略
console.log(regexp.lastIndex);//0
regexp.exec(str)
console.log(regexp.lastIndex);//5
console.log( regexp.exec(str) );
结果: 0 5 [ 'world', index: 7, input: 'Hello, world!', groups: undefined ]
如果正则表达式带有修饰符y,则搜索讲精确地在regexp.lastIndex位置执行,不会再进行一步 将上面的修饰符由g替换为y,现在最后一行找不到匹配项,因为在5的位置没有匹配项
let str = 'Hello, world!';
let regexp = /\w+/y; // 没有修饰符 "g",lastIndex 属性会被忽略
console.log(regexp.lastIndex);//0
regexp.exec(str)
console.log(regexp.lastIndex);//5
console.log( regexp.exec(str) ); //null