js 正则表达式
js正则表达式
'ajanuw'.replace(/a/g, 'x'); //"xjxnuw"
'ajanuw'.replace(new RegExp('a', 'g'), 'x'); //"xjxnuw"
修饰符 flags
g 全局匹配, `lastIndex`无效
i 忽略大小写
m 多行搜索
u 启用对unicode的支持
s 让.能匹配到\n,就可以多行匹配
y 执行“粘性”搜索,匹配从目标字符串的当前位置开始,可以使用y标志,使用后将从`lastIndex`位置开始匹配
元字符
\t 水平制表符
\v 垂直制表符
\n 换行符
\r 回车符
\0 | 空字符
\f 换页符
\cX 控制字符 ctrl+x
字符类
[abc] // a或b或c
[^abc] // 不是a或b或c
范围内
[a-z] // a到z之间的全部
[a-zA-Z] // 大小写全部匹配
[0-9] // 数字范围
预定义类
. 除了回车换行之外的所有字符
\d 数字
\D `非`数字
\s 空白符
\S `非`空白符
\w 字母,数字,下划线
\W `非`字母,数字,下划线
[^] 匹配任何字符,包括换行符。在多行字符串上非常有用
边界
^xx 从xx开始
xx$ 从xx结束
\b 单词边界
\B `非`单词边界
量词
| 字符 | 含义 |
|---|---|
| ? | 出现0或1(最多出现一次) |
| + | 一次或多次(至少出现一次) |
| * | 出现0次或多次(任意次) |
{n} |
出现n次 |
{n, m} |
出现n次到m次 |
{n, } |
至少出现n次 |
贪婪模式和非贪婪模式
匹配数字3-5次, 默认匹配最大值5
'123456'.replace(/\d{3,5}/, 'x'); //"x6"
在量词后面加上?号进入fei贪婪模式,匹配3次结束
'123456'.replace(/\d{3,5}?/, 'x'); //"x456"
分组( ) or |
'x1x1x1'.replace(/(x\d){2}/g, '-'); // 匹配x1连续出现两次
'x1x1x1'.replace(/x\d{2}/g, '-'); //匹配数字出现2次
反向引用
$`: 匹配部分的前一部分字符串
$&: 匹配的字符串
$': 还没有匹配的剩余字符串
捕获分组内容 最多捕获7个
'ajanuw'.replace(/(\w{3})(.*)/, '$2 $1')
"nuw aja"
?: 可以忽略捕获,只需要分组
'ajanuw'.replace(/(\w{3})(?:.*)/, '$2 $1')
"$2 aja"
/(?<word>[a-z]+)!\k<word>$/.test('a!a') // true
/(?<word>[a-z]+)!\1$/.test('a!a') // 更上面一样true
/(?<word>[a-z]+)!\k<word>!\1$/.test('a!a!a') // 两种混写true
"hello world".replace(
/(?<first>[a-z]+)\s(?<last>\w+)/,
(...args) => {
let g = args[args.length - 1];
// 没匹配上的话值为 undefined
let { first, last } = g;
console.log(g);
console.log(first, last);
});
前瞻匹配(正相前瞻, 负相前瞻)
断言部分 不参与匹配
// 匹配 -后有单词的替换为_
// 正相前瞻
'text-danger-'.replace(/-(?=[a-zA-Z])/g, '_') // text_danger- 最后一个-不符合要求
// 负相前瞻
'text-danger-'.replace(/-(?![a-zA-Z])/g, '_') // text-danger_ 更上面相反
Lookbehind断言 (于前瞻相反)
// 匹配 -前有单词的替换为_
'text-danger-'.replace(/(?<=[a-zA-Z])-/g, '_') // "text_danger_"
// 匹配 -前没有有单词的替换为_
'text-danger--'.replace(/(?<![a-zA-Z])-/g, '_') // "text-danger-_"
rep.lastIndex 当前表达式匹配内容的最后一个字符的下一个位置
rep.source 正则表达式的文本内容
表达式方法
- test方法
test方法, 判断一个str里面是否含有正则匹配的参数
返回 false 或 true
会在内部调用rep.lastIndex, 对参数进行迭代
/\d{3}/.test('ajanuw'); //false 判断文本中连续出现3次的数字
- exec方法
/((\w){3})/g.exec('ajanuw')
返回了一个数组
var res = ["aja", "aja", "a", index: 0, input: "ajanuw"]
res[0] 代表表达式所匹配的内容
res[1] 第一个 打组匹配的内容
res[2] 第2个 打组匹配的内容 以此类推
res[3] index代表在字符串中第几个开始匹配成功
res[4] input 匹配的文本
如果匹配失败 返回null
如果加上 g标志,会触发lastIndex
- search方法
参数可以是 正则 或string
'ajanuw'.search(/\d/); -1
在字符串中查找, 找到返回index,没找到返回-1
忽略g标志
- match方法
匹配成功返回数组, 否者返回 null
'a b c'.match('c')
["c", index: 4, input: "a b c"]
- replace 替换
大概含有4各参数
1. 匹配到的字符串
2. 打组内容 g1, g2, g3不等
3. 匹配项在字符串中的index
4. 原字符串
'ajanuw'.replace(/\w{3}/, function(match){
// match 匹配的结果
console.log(match);
var args = Array.prototype.slice.call(arguments, 1); // 所有的打组
var str = args.splice(args.length - 1, 1); // 获取元字符
var index = args.splice(args.length - 1, 1) // 获取 index
console.log(args);
})
命名捕获组
const RE_DATE = /(?<year>[0-9]{4})-(?<month>[0-9]{2})-(?<day>[0-9]{2})/;
const matchObj = RE_DATE.exec('1999-12-31');
const year = matchObj.groups.year; // 1999
const month = matchObj.groups.month; // 12
const day = matchObj.groups.day; // 31
console.log(year, month, day) // 1999 12 31
console.log(matchObj) // ["1999-12-31", "1999", "12", "31"]
匹配回车换行
function f(s) {
s = s.replace(/\\(\w)/g, "\\\\$1");
console.log(s.split(/\r\n|\r|\n/));
}
获取当前匹配的字符串在第几行
function f(s) {
s = s.replace(/\\(\w)/g, "\\\\$1");
let startIndex = 0;
let m = s.match(/hello/); // 匹配hello
let startStr = s.substr(startIndex, m.index); // 斩出hello之前的字符串
console.log(startStr.match(/\r\n|\r|\n/g).length); // 获取有多少个换行
startIndex = m.index;
let endIndex = startIndex + m[0].length;
}

浙公网安备 33010602011771号