符号
数字.字母等
| 符号 | 意义 | []中使用 |
|---|---|---|
| \d | 数字 | [0-9] |
| \D | 非数字 | [^0-9] |
| \s | 空白符 | [ \f\n\r\t\v] |
| \S | 非空白符 | [^ \f\n\r\t\v] |
| \w | 字母和数字和下划线 | [A-Za-z0-9_] |
| \W | 非字母和数字和下划线 | [^A-Za-z0-9_] |
| [\u4e00-\u9fa5] | 中文 | |
| [\u4E00-\u9FA5A-Za-z0-9_] | 中文、英文、数字包括下划线 |
定位符
| 符号 | 意义 |
|---|---|
| \b | 单词边界 |
| \B | 非单词边界 |
| $ | 结尾 |
| ^ | 开头 |
代表类
| 符号 | 意义 | 正则使用(//g) |
|---|---|---|
| . | 任意字符 | .+(任意字符一个或者多个) |
| | | 或者 | a|b(a或者b都可以匹配到) |
| [] | 范围类 | [0-9](代表数字) |
| [^] | 非范围类 | [^0-9](非数字) |
匹配使用的符号
| 符号 | 意义 |
|---|---|
| /g | 全局搜索 |
| /i | 区分大小写 |
| /m | 多行搜索 |
/[0-9]/gmi
非打印字符
| 符号 | 含义 |
|---|---|
| \t | 水平制表符 |
| \v | 垂直制表符 |
| \n | 换行符 |
| \r | 回车符 |
| \f | 换页符 |
限定符
| 符号 | 使用 | 含义 |
|---|---|---|
| ? | \d? | 数字0到1个 |
| + | \d+ | 数字一个或者多个 |
| {1} | \d{1} | 数字1个 |
| {1, 5} | \d{1, 5} | 数字1到5个 |
| {n, } | \d{n, } | 数字至少出现一次 |
| * | \d* | 0个或者任意一个 |
特殊字符
| 字符 | 说明 |
|---|---|
| ^ | 匹配输入字符串的开始位置。要匹配 "^" 字符本身,请使用 "^" |
| $ | 匹配输入字符串的结尾位置。要匹配 "$" 字符本身,请使用 "$" |
| ( ) | 标记一个子表达式的开始和结束位置。要匹配小括号,请使用 "\(" 和 "\)" |
| [ ] | 用来自定义能够匹配 '多种字符' 的表达式。要匹配中括号,请使用 "\[" 和 "\]" |
| { } | 修饰匹配次数的符号。要匹配大括号,请使用 "\{" 和 "\}" |
| . | 匹配除了换行符(\n)以外的任意一个字符。要匹配小数点本身,请使用 "\." |
| ? | 修饰匹配次数为 0 次或 1 次。要匹配 "?" 字符本身,请使用 "?" |
| + | 修饰匹配次数为至少 1 次。要匹配 "+" 字符本身,请使用 "\+" |
| * | 修饰匹配次数为 0 次或任意次。要匹配 "*" 字符本身,请使用 "\*" |
| | | 左右两边表达式之间 "或" 关系。匹配 "|" 本身,请使用 "\|" |
断言
| 字符 | 含义 |
|---|---|
| x(?=y) | 先行断言: y紧跟x的情况下匹配x。例如,对于/Jack(?=Sprat)/,“Jack”在跟有“Sprat”的情况下才会得到匹配./Jack(?=Sprat)/ “Jack”后跟有“Sprat”或“Frost”的情况下才会得到匹配。不过, 匹配结果不包括“Sprat”或“Frost”。 |
| x(?!y) | 负向先行断言: x后无y紧随的情况下匹配x。例如,对于/\d+(?!\。)/,数字后没有跟随小数点的情况下才会得到匹配。对于/\d+(?!.)/.exec(3.141),“3”得到匹配,“141”则无。 |
| (?<=y)x | 后行断言: x紧随y的情况下匹配x。例如,对于/(?<=Jack)Sprat/,“Sprat”紧随“Jack”时才会得到匹配。对于/(?<=Jack)Sprat,“Sprat”在紧随“Jack”或“Tom”的情况下才会得到匹配。不过,匹配结果中不包括“Jack”或“Tom”。 |
| (?<!y)x | 负向后行断言: x不紧随y的情况下匹配x。例如,对于/(?<!-)\d+/,数字紧随-符号的情况下才会得到匹配。对于/(?<!-)\d+/.exec(3) ,“3”得到匹配。 而/(?<!-)\d+/.exec(-3)的结果无匹配,这是由于数字之前有-符号。 |
示例
先行断言
// JS Lookahead assertion x(?=y)
let regex = /First(?= test)/g;
console.log('First test'.match(regex)); // [ 'First' ]
console.log('First peach'.match(regex)); // null
console.log('This is a First test in a year.'.match(regex)); // [ 'First' ]
console.log('This is a First peach in a month.'.match(regex)); // null
负向先行断言
console.log(/\d+(?!\.)/g.exec('3.141')); // [ '141', index: 2, input: '3.141' ]
后行断言
let oranges = ['ripe orange A ', 'green orange B', 'ripe orange C',];
let ripe_oranges = oranges.filter( fruit => fruit.match(/(?<=ripe )orange/));
console.log(ripe_oranges); // [ 'ripe orange A ', 'ripe orange C' ]
?: 或者捕获符
// [00:00.000] 作曲 : 接个吻,开一枪
// [00:01] 作词 : 接个吻,开一枪/王东旭/Lambert
let time = elem.match(/\[(\d{2,}):(\d{2})(?:\.(\d{2,3}))?]/g)
console.log(time)
// [00:00.000]
// [00:01]
JavaScript 正则表达式
分组
正则中用()来表示分组$1,
n
replace中的分组
// ([a-z]\d){3} 3组
'a1b2c3d4'.replace(/([a-z]\d){3}/g, 'X')
// Xd4
match中的分组
var str = 'For more information, see Chapter 3.4.5.1';
var re = /see (chapter \d+(\.\d)*)/i;
var found = str.match(re);
console.log(found);
// logs [ 'see Chapter 3.4.5.1',
// 'Chapter 3.4.5.1',
// '.1',
// index: 22,
// input: 'For more information, see Chapter 3.4.5.1' ]
$1,
n符号
'a1b2c3d4'.replace(/(a1)(b2).+/g, '$1$2')
// a1b2
// $1='a1' $2=b2
方法
示例
replace(替换)
const p = 'The quick brown fox jumps over the lazy dog. If the dog reacted, was it really lazy?';
const regex = /dog/gi;
console.log(p.replace(regex, 'ferret'));
// expected output: "The quick brown fox jumps over the lazy ferret. If the ferret reacted, was it really lazy?"
console.log(p.replace('dog', 'monkey'));
// expected output: "The quick brown fox jumps over the lazy monkey. If the dog reacted, was it really lazy?"
match(多行返回数组)
var str = 'For more information, see Chapter 3.4.5.1';
var re = /see (chapter \d+(\.\d)*)/i;
var found = str.match(re);
console.log(found);
// logs [ 'see Chapter 3.4.5.1',
// 'Chapter 3.4.5.1',
// '.1',
// index: 22,
// input: 'For more information, see Chapter 3.4.5.1' ]
// 'see Chapter 3.4.5.1' 是整个匹配。
// 'Chapter 3.4.5.1' 被'(chapter \d+(\.\d)*)'捕获。
// '.1' 是被'(\.\d)'捕获的最后一个值。
// 'index' 属性(22) 是整个匹配从零开始的索引。
// 'input' 属性是被解析的原始字符串。
match多行搜索的时候分组会出现无法获取分组信息
let lrc = `[00:00.000] 作曲 : 接个吻,开一枪
[00:01] 作词 : 接个吻,开一枪/王东旭/Lambert
[00:05.260]编曲:接个吻,开一枪
[00:11.570]早上光照在房间 穿上新衬衫
[00:14.460]镜子里我又长高了些
[00:16.960]和同学吃火锅然后开黑带妹
[00:19.280]一起狼人杀不用上学就不累
[00:21.630]发条祝福传给你 请你别忘记`
let res = lrc.match(/\[(.+)\]/gm)
console.log(res)
// 0: "[00:00.000]"
// 1: "[00:01]"
// 2: "[00:05.260]"
// 3: "[00:11.570]"
// 4: "[00:14.460]"
// 5: "[00:16.960]"
// 6: "[00:19.280]"
// 7: "[00:21.630]"]
matchAll(针对match多行搜索)
返回一个包含所有匹配正则表达式的结果及分组捕获组的迭代器。
let lrc = `[00:00.000] 作曲 : 接个吻,开一枪
[00:01] 作词 : 接个吻,开一枪/王东旭/Lambert
[00:05.260]编曲:接个吻,开一枪
[00:11.570]早上光照在房间 穿上新衬衫
[00:14.460]镜子里我又长高了些
[00:16.960]和同学吃火锅然后开黑带妹
[00:19.280]一起狼人杀不用上学就不累
[00:21.630]发条祝福传给你 请你别忘记`
let res = lrc.matchAll(/\[(.+)\]/gm)
console.log([...res])
// 0: (2) ["[00:00.000]", "00:00.000", index: 0, input: ..., groups: undefined]
// 1: (2) ["[00:01]", "00:01", index: 25, input:...
...
exec
var re = /quick\s(brown).+?(jumps)/ig;
var result = re.exec('The Quick Brown Fox Jumps Over The Lazy Dog');
// result log:
/**
0: "Quick Brown Fox Jumps"
1: "Brown"
2: "Jumps"
groups: undefined
index: 4
input: "The Quick Brown Fox Jumps Over The Lazy Dog"
**/
test(返回 true 或 false)
let str = 'hello world!';
let result = /^hello/.test(str);
console.log(result);
// true
search()
方法执行正则表达式和 String 对象之间的一个搜索匹配。
const paragraph = 'The quick brown fox jumps over the lazy dog. If the dog barked, was it really lazy?';
// any character that is not a word character or whitespace
const regex = /[^\w\s]/g;
console.log(paragraph.search(regex));
// expected output: 43
console.log(paragraph[paragraph.search(regex)]);
// expected output: "."