Js-正则表达式

1、初体验正则表达式

let hd = 'houdunren2200hdcms9988'

console.log(parseInt(hd));
// ---> NaN: not a number

console.log(Number.isNaN(parseInt(hd)));
// true

let numbers = [...hd].filter(value => !Number.isNaN(parseInt(value)));
console.log(numbers.join(''));
// 22009988

let reg_number = hd.match(/\d/g);
console.log(reg_number.join(''));
// 22009988

2、字面量创建正则表达式

let hd = 'houdunren.com';

// 检测字符串中是否包括u这个字符, 但是一般不能识别变量
console.log(/u/.test(hd));
// true

// 可以通过以下方式来识别变量:eval, 相对比较麻烦
let a = 'u';
console.log(eval(`/${a}/`).test(hd));
// true

3、使用对象创建表达式

let hd = 'houdunren.com';

let a = 'u';
let reg = new RegExp(a, 'g');
// let reg = new RegExp('u', 'g');
console.log(reg.test(hd));

// 字符串的替换
let b = 'aaa';
let c = b.replace(/\w/g, search=>{console.log(search); return search + '->'});
console.log(c);
// a
// a
// a
// a->a->a->

// 通过用户输入来控制文本颜色
let button = document.createElement('button');
let str = 'houdunren.com';
button.innerText = str;
button.onclick = function (){
    let con = prompt('请输入检测的内容,支持正则表达式');
    let reg = new RegExp(con, 'g');
    this.innerHTML = str.replace(reg, search=> `<span style="color:red">${search}</span>`);
}
document.body.appendChild(button);

4、选择符的使用

let hd = 'houdunren';

// 只要两边任意一个满足就可以了, | 表示 or
console.log(/u|@/.test(hd));
// true

// {7, 8} 限制匹配次数表示至少出现7-8次, 但是可以大于8次, /010-\d{7, 8}
let tel = '010-9999999'
console.log(/010-\d{7,8}|020-\d{7,8}/.test(tel));
// true
console.log(/(010|020)-\d{7,8}/.test(tel));
// true

5、原子表与原子组中的选择符

// [] ()

// 原子表
// 表示匹配 [] 中的最小单元元素,只要被匹配的最小单元元素存在 [], 那么就是成立
// 下面表示匹配 1 or 2 or 3 or 4 ......
let reg = /[123456]/g

let hd = '12df13';
console.log(hd.match(reg));
// [ '1', '2', '1', '3' ]


// 原子组 (), 匹配得是一个整体
let my_reg = /(12|34)/g;
console.log(hd.match(my_reg));
// [ '12' ]

6、正则表达式中得转义

let price = 23.14;

// 转义就是原本的字符有多个含义,需要转化为自己想要的含义
// . 表示除了换行以外得任何字符,如果需要匹配这个符号得话需要转义
// \d+ 表示匹配一个或者一个以上的数字 /\d+\.\d+/
console.log(/\d+\.\d+/.test(price + ''));
// true

// \ 的方式是转义符号,也就是说 \d转义的是 d这个符号,转义之后还是 d
console.log('\d+\.\d+');
// d+.d+

// 所以需要转义符号来转义 \ 本身
console.log('\\d+\\.\\d+');
// \d+\.\d+

// 于是在new出来的正则表达式里面最好用上第二种方法才会有效
// 这个声明里面传入的还是一个字符串
let reg = new RegExp('\\d+\\.\\d+');
console.log(reg.test(price + ''));

let url = 'https://www.baidu.com';
let r = /https?:\/\/\w+\.\w+\.\w+/
console.log(r.test(url));
// true

7、字符边界约束

let str = '6etrq234sf';
// ^ 表示的是以什么开头
// $ 表示的是以什么结尾
// 强制要求
// 表示是否以数字开头, \d 默认匹配到的是一位数字
let r = /^\d/;
console.log(r.test(str));

let input = document.createElement('input');
let div = document.createElement('div');
div.innerHTML = '匹配后的字符:';
document.body.appendChild(input);
document.body.appendChild(div);
input.addEventListener('keyup', function (){
    // 只有位数满足情况的下才会显示, 现在表示整个字符串满足3-6位才会显示
    // i 表示忽略大写或者小写
    div.innerHTML = '匹配后的字符:' + this.value.match(/^[a-z]{3,6}$/i);
})

8、数值与空白元字符

// 元字符
let hd = 'houdunren 2020';
let r1 = /\d\d\d\d/;    // 这里表是的是匹配连续的四个数字
console.log(hd.match(r1));
// [ '2020', index: 10, input: 'houdunren 2020', groups: undefined ]

let phone_number = '张三:010-99999999, 李四:020-88888888';
let r2 = /\d{3}-\d{7,8}/g
console.log(phone_number.match(r2));
// [ '010-99999999', '020-88888888' ]

// \D 表示除了数字其他所有的都匹配,和原来的表示的是一个互补的关系
let r3 = /\D+/;
console.log(hd.match(r3));
// [ 'houdunren ', index: 0, input: 'houdunren 2020', groups: undefined ]

// 匹配中文的一种方式, 现在这里看不懂没有关系, 原子表:除了里面的元素我都要
let r4 = /[^-\d:,\s]+/g;
console.log(phone_number.match(r4));
// [ '张三', ' 李四' ]

// \s, teb, 制表,换行符都算是空白, \s 专门来匹配空白, s -> space
let r5 = /\s/; // 这里表示匹配空白
console.log(r5.test('\nhd')); // 匹配到的第一个是空白,所以为真, 或者说只匹配到了一个空白
// true
let r6 = /\S/; // 这里表示除了空白, 还有其他字符
console.log(r6.test(' \nhd'));
// true

9、w与W元字符

let hd = 'houdunren2020';
// \w+ 匹配到的是字母,数字,下划线, ‘-’中划线是匹配不到的, '@'等特殊字符是匹配不到的
// \W 除了字母,数字,下划线
let r1 = /\w+/;
console.log(hd.match(r1));
// [
//     'houdunren2020',
//     index: 0,
//     input: 'houdunren2020',
//     groups: undefined
// ]

let email = '3410945466@qq.com';
let r2 = /^\w+@\w+\.\w+$/;
console.log(email.match(r2));
// [
//     '3410945466@qq.com',
//     index: 0,
//     input: '3410945466@qq.com',
//     groups: undefined
// ]

let r4 = /\W/;
console.log(email.match(r4));
// [ '@', index: 10, input: '3410945466@qq.com', groups: undefined ]

// 原子表 [a-z]\w : 表示 a-z 中的一位字母 + 数字,字母,下划线,
// 这里规定第一个必须不是数字, 如果不加入限制,表示只要字符串中存在就返回真
let r5 = /^[a-z]\w{4,9}$/;
let s1 = '3rewqr';
let s2 = 'wertwet';
console.log(r5.test(s1)); // false
console.log(r5.test(s2)); // true

10、点元字符的使用

// . 表示匹配除了换行符以外的任何字符, 可以匹配空格或者制表符
// 也就是说 . 是包括了 \d 和 \w 两个匹配符号的
let hd = 'houdunren';
let r1 = /.+/;
console.log(hd.match(r1));
// [ 'houdunren', index: 0, input: 'houdunren', groups: undefined ]

// 需要匹配字符串中的 . 需要转义一下 \.
let url = 'https://www.baidu.com';
let r = /https?:\/\/\w+\.\w+\.\w+/
console.log(r.test(url));
// true

let s1 = `
    hundunren.com
    baidu.com
`
// 由于没有设置起始位置的匹配项目,于是就会一直向后找匹配字符,只要找到了符合条件的就会返回
console.log(s1.match(r1));
// [
//     '    hundunren.com',
//     index: 1,
//     input: '\n    hundunren.com\n    baidu.com\n',
//     groups: undefined
// ]

// 末尾添加 s 可以理解为 . 可以来匹配换行符, 或者将原来的换行符去掉视为单行
let r2 = /.+/s;
console.log(s1.match(r2));
// [
//     '\n    hundunren.com\n    baidu.com\n',
//     index: 0,
//     input: '\n    hundunren.com\n    baidu.com\n',
//     groups: undefined
// ]

let tel = '010 - 99999999';
// 空格也是一个普通字符, 可以用 \s 或者 直接敲一个空格表示
let r3 = /\d+\s- \d{8}/;
console.log(tel.match(r3));
// [
//     '010 - 99999999',
//     index: 0,
//     input: '010 - 99999999',
//     groups: undefined
// ]

11、匹配所有字符

let s = `
<span>
    hello @@@
    bad 
</span>
`

let s1 = 'ab';
// + 表示前面的字符匹配一个或者多个
let r1 =  /<span>[\s|\S]+<\/span>/;
let r2 =  /<span>[\d|\D]+<\/span>/;
console.log(s.match(r1));
// [
//     '<span>\n    hello @@@\n    bad \n</span>',
//     index: 1,
//     input: '\n<span>\n    hello @@@\n    bad \n</span>\n',
//     groups: undefined
// ]

12、i与g模式修正符号

// i 表示忽略大小写
// g 表示全局匹配,而不是只匹配一个
// 每次匹配都会从上次满足条件的最后一位开始新的匹配
// 可以连续添加多个修真符 /[\s|\S]/ig, 和顺序没有关系

13、m多行匹配修正符号示例

let hd = `
#1 js,200 yuan #
#2 python,200 yuan #
#3 php,200 yuan # dont need
#4 java,200 yuan #
`
// * 表示前面的字符为0个或者多个
// m 表示对于每一行都是单独对待
let r = /^\s*#\d+\s+.+\s+#$/gm;
console.log(hd.match(r));
// [ '\n#1 js,200 yuan #', '#2 python,200 yuan #', '#4 java,200 yuan #' ]

let data = hd.match(r).map(value => {
    value = value.replace(/\s*#\d+\s*/, '').replace(/#/, '');
    let [name, price] = value.split(',');
    return {name, price};
})
console.log(data);
// [
//     { name: 'js', price: '200 yuan ' },
//     { name: 'python', price: '200 yuan ' },
//     { name: 'java', price: '200 yuan ' }
// ]

14、汉字与字符属性

let hd = 'houdunren2010';

// u 表示按 unicode, utf-8 匹配

let r = /\p{L}/gu;
console.log(hd.match(r));
// [
//     'h', 'o', 'u',
//     'd', 'u', 'n',
//     'r', 'e', 'n'
// ]

let s1 = 'houdunren2010.交友,加哟普';
let r1 = /\p{P}/gu;
console.log(s1.match(r1));
// [ '.', ',' ]

// 可通过 doc.houdunren.com 查看
let r2 = /\p{sc=Han}/gu;
console.log(s1.match(r2));
// [ '交', '友', '加', '哟', '普' ]

15、lastindex的属性

let hd = 'houdunren';
let r = /\w/g;
// 只有在全局模式下才会记录上一次的字符的位置
console.log(r.lastIndex);
console.log(r.exec(hd));
// 0
// [ 'h', index: 0, input: 'houdunren', groups: undefined ]
console.log(r.lastIndex);
console.log(r.exec(hd));
// 1
// [ 'o', index: 1, input: 'houdunren', groups: undefined ]

let res;
// 这个表达式表示先赋值,然后在判断赋值后的变量的属性的真假
while (res = r.exec(hd)){
    console.log(res);
}
// [ 'u', index: 2, input: 'houdunren', groups: undefined ]
// [ 'd', index: 3, input: 'houdunren', groups: undefined ]
// [ 'u', index: 4, input: 'houdunren', groups: undefined ]
// [ 'n', index: 5, input: 'houdunren', groups: undefined ]
// [ 'r', index: 6, input: 'houdunren', groups: undefined ]
// [ 'e', index: 7, input: 'houdunren', groups: undefined ]
// [ 'n', index: 8, input: 'houdunren', groups: undefined ]

16、有效的y模式

let hd = 'houdunren';
let reg = /u/g;

console.log(reg.exec(hd));
console.log(reg.lastIndex);
console.log(reg.exec(hd));
console.log(reg.lastIndex);
// [ 'u', index: 2, input: 'houdunren', groups: undefined ]
// 3
// [ 'u', index: 4, input: 'houdunren', groups: undefined ]
// 5

// y 表示必须要一直连续的满足条件才会匹配
let hd1 = 'uhoudunren';
let reg2 = /u/y;
console.log(reg2.exec(hd1));
console.log(reg2.lastIndex);
console.log(reg2.exec(hd1));
console.log(reg2.lastIndex);
// [ 'u', index: 0, input: 'uhoudunren', groups: undefined ]
// 1
// null
// 0

// 匹配连续的数字
let s = '加qq,11111111,11312245,345634,快来加我';
// ? 表示前面的字符可以存在或者不存在
let reg3 = /(\d+),?/y;
// 更改起始匹配位置
reg3.lastIndex = 4;
console.log(reg3.exec(s));
// [
//     '11111111,',
//     '11111111',
//     index: 4,
//     input: '加qq,11111111,11312245,345634,快来加我',
//     groups: undefined
// ]
console.log(reg3.exec(s));
// [
//     '11312245,',
//     '11312245',
//     index: 13,
//     input: '加qq,11111111,11312245,345634,快来加我',
//     groups: undefined
// ]
console.log(reg3.exec(s));
// [
//     '345634,',
//     '345634',
//     index: 22,
//     input: '加qq,11111111,11312245,345634,快来加我',
//     groups: undefined
// ]
console.log(reg3.exec(s));
// null

17、原子表的使用

let hd = 'houdunren';
let r1 = /ue/;
console.log(hd.match(r1));
// null

// 放到原子表里面表示按表里面的单个原子进行匹配操作
let r2 = /[ue]/;
console.log(hd.match(r2));
// [ 'u', index: 2, input: 'houdunren', groups: undefined ]

// 匹配一个电话号码
let tel = '2022-02-23';
let reg = /^\d{4}-\d{2}-\d{2}$/;
console.log(tel.match(reg));
// [ '2022-02-23', index: 0, input: '2022-02-23', groups: undefined ]

// ([-\/]) 表示创建一个组,将原子表放到组里面, 然后 \1 表示这里和第一个组的匹配类型应该一致
let tel1 = '2022/02-23';
let tel2 = '2022/02/23';
let reg2 = /^\d{4}([-\/])\d{2}\1\d{2}$/;
console.log(tel1.match(reg2));
// null
console.log(tel2.match(reg2));
// [ '2022/02/23', '/', index: 0, input: '2022/02/23', groups: undefined ]

18、区间匹配

let hd = '2010';
let r1 = /[0-9]+/g;
console.log(hd.match(r1));
// [ '2010' ]

let s = 'houdunre';
let r2 = /[a-z]+/;
console.log(s.match(r2));
// [ 'houdunre', index: 0, input: 'houdunre', groups: undefined ]

// 指定必须以字母开始的匹配, 用户名必须是6——7位
let reg = /^[a-z]\w{3,6}$/i;

19、排除匹配

let hd = 'houdunren.com';
// ^ 表示原子表中除了 u 和 e 其他的都要匹配
let reg = /[^ue]/gi;
console.log(hd.match(reg));
// [
//     'h', 'o', 'd', 'n',
//     'r', 'n', '.', 'c',
//     'o', 'm'
// ]


let s = '张三:010-99999999,李四:020-88888888';
// 原子表里面的 ^ 有非的意思:表示除了 : , 数字, -, , , 其他的我都要;
// 原子表里面的 - 需要转义
let reg1 = /[^\d:\-,]+/g;
console.log(s.match(reg1));
// [ '张三', '李四' ]

20、原子表字符不解析

let hd = '(houdunren).+';

// 括号放到原子表里面将解析为括号, .+ 放到里面也是表示原来字符串的含义
// 就是 字符串中的 .和 +号
// 即使转义以后,还是原来的属性, 只是保留原字符中的本意
let reg = /[(.+)]/

21、使用原子表匹配所有的内容

let hd = `
    houdun
    ren
`;

// 由于 . 不能匹配换行符,那么就相当于一行一行的进行匹配
// 但是如果加了修饰符号 s , 可以理解为可以匹配 \n
let r1 = /.+/g;
console.log(hd.match(r1));
// [ '    houdun', '    ren' ]


// 通过互补思想可以匹配到所有的字符
let r2 = /[\s\S]+/;
console.log(hd.match(r2));
// [
//     '\n    houdun\n    ren\n',
//     index: 0,
//     input: '\n    houdun\n    ren\n',
//     groups: undefined
// ]

22、正则操作dom元素

let dom = `
    <p>title</p>
    <h1>top title
        new line
    </h1>
    <h2>sub title</h2>
`;

// 这里的括号表示分组,分成一个原子组, \1 表示和第一个原子组的匹配是一致的
let reg = /<(h[1-6])>[\s\S]*<\/\1>/gim;
let new_dom = dom.replace(reg, '');
console.log(new_dom);
// <p>title</p>

23、认识原子组

let dom = `
    <h1>top title
        new line
    </h1>
    <h2>sub title</h2>
`;
// 分成组之后就是 可以通过 \1, \2, \3 来代替前面的组
let reg = /<(h[1-6])>[\s\S]*<\/\1>/i;
console.log(dom.match(reg));
// [
//     '<h1>top title\n        new line\n    </h1>',
//     'h1', ----> 这里表示匹配了第一个原子组
//     index: 5,
//     input: '\n    <h1>top title\n        new line\n    </h1>\n    <h2>sub title</h2>\n',
//     groups: undefined
// ]
// 获得的结果中索引值为 1 的表示匹配了的第一个原子组, 在这里就是 h1
// 如果有多个原子组,那么就会依次累加

24、邮箱验证中原子组的判断

let mail = '3410945446@qq.com';
// 后面的是一个原子组,组里面的表示的是一个整体
// 这里的原子组里面有多个 or 相连
// [\w\-]+\. 表示 qq. 或者 134. 等匹配
// ([\w\-]+\.)+ 表示里面的组可以有多个匹配, 例如 132.ewtr.qq. 等连续匹配
let reg = /^[\w\-]+@([\w\-]+\.)+(com|org|cc|cn|net)$/i;
console.log(mail.match(reg));
// [
//     '3410945446@qq.com',
//     'qq.',   ---> 这里表示的是第一个分组
//     'com',   ---> 这里表示的是第二个分组
//     index: 0,
//     input: '3410945446@qq.com',
//     groups: undefined
// ]

25、原子组引用完成替换操作

let s = `
<h1>hello</h1>
<span>你好</span>
<h2>cnn</h2>`;
// 将标题 h1 和 h2换成 p 标签

let reg = /<(h[1-6])>([\s\S]+)<\/\1>/gi;
console.log(s.match(reg));
// [ '<h1>hello</h1>', '<h2>cnn</h2>' ]

// $2 表示拿到的是第二个分组里面的元素
let s1 = s.replace(reg, `<p>$2</p>`);
console.log(s1);
// <p>hello</p>
// <span>你好</span>
// <p>cnn</p>

// 相当于以下写法的简写,  这里的回调函数传入的是正则匹配的结果,也就是一个数组
let s2 = s.replace(reg, (p0, p1, p2)=>{
    console.log(p0, p1, p2);
    // <h1>hello</h1> h1 hello
    // <h2>cnn</h2> h2 cnn
    return `<p>${p2}</p>`;
})
console.log(s2);
// <p>hello</p>
// <span>你好</span>
// <p>cnn</p>

26、嵌套分组与不记录组

let url = 'https://www.baidu.com';
let reg = /https:\/\/\w+\.\w+\.(com|org|cn)/gi;
console.log(url.match(reg));
// [ 'https://www.baidu.com' ]

// 将域名进行分组, 分组里面的括号里面加上 ?: 表示不用对这里表示保留, 所以第一个
// 分组括号里面的就是一个整体, 忽略掉里面的分组
let reg2 = /https:\/\/(\w+\.\w+\.(?:com|org|cn))/i;
console.log(url.match(reg2));
// [
//     'https://www.baidu.com',
//     'www.baidu.com',
//     index: 0,
//     input: 'https://www.baidu.com',
//     groups: undefined
// ]

// 不通过 ?: 的形式
let reg3 = /https:\/\/(\w+\.\w+\.(com|org|cn))/i;
console.log(url.match(reg3));
// [
//     'https://www.baidu.com',
//     'www.baidu.com',
//     'com', ----> 如果不通过 ?: 的形式这里会多出一个分组
//     index: 0,
//     input: 'https://www.baidu.com',
//     groups: undefined
// ]

// 这里的 ? 表示前面的 s 元素匹配0次或者是1次
// (\w+\.)? 在这里表示 www. 可以有 也可以没有
let reg4 = /https?:\/\/((\w+\.)?\w+\.(?:com|org|cn))/i;
let s = 'http://baidu.com';
console.log(s.match(reg4));
// [
//     'http://baidu.com',
//     'baidu.com',
//     undefined, ---> 由于没有 www. 于是这里是 undefined, 如果不想记录分组,所以加上 ?: 就可以了
//     index: 0,
//     input: 'http://baidu.com',
//     groups: undefined
// ]

27、多种重复匹配的基本使用

let hd = 'hddddddddd';
// hd+ 表示开头是 h, 然后后面的 + 修饰前面的元素d, 也就是说d可以一直多次匹配下去
// + 表示匹配一个或这多个, 是贪婪匹配
//  贪婪匹配是越多越好的意思,也就是说是尽可能多次匹配
let reg = /hd+/;
console.log(hd.match(reg));
// [ 'hddddddddd', index: 0, input: 'hddddddddd', groups: undefined ]

// * 表示匹配的次数为 0 个或者 多个
let reg2 = /hd*/;
console.log(hd.match(reg2));
// [ 'hddddddddd', index: 0, input: 'hddddddddd', groups: undefined ]

// {count_min, count_max} 表示修饰限定匹配次数,修饰前面的那个元素
// 这里最多只能匹配3个相同的元素,最少匹配一个h元素
// {0,} : 这里表示的是匹配0次或者无限次
let reg3 = /hd{1,3}/;
console.log(hd.match(reg3));
// [ 'hddd', index: 0, input: 'hddddddddd', groups: undefined ]
e

28、重复匹配对原子组的影响与电话号正则

let s = 'hdddd';
// 这里的 + 前面的元素是括号里面的分组的那个整体
let r1 = /(hd)+/;
console.log(s.match(r1));
// [ 'hd', 'hd', index: 0, input: 'hdddd', groups: undefined ]

let tel = '010-88888888';
let r = /^0\d{2,3}-\d{7,8}$/;
console.log(tel.match(r));
// [ '010-88888888', index: 0, input: '010-88888888', groups: undefined ]

29、网站用户名验证

let input = document.createElement('input');
document.body.appendChild(input);
let out_put = document.createElement('div');
let label_ = '输出内容:';
out_put.innerHTML = label_;
document.body.appendChild(out_put);
input.addEventListener('keyup', ev => {
    let value = ev.target.value;
    let reg = /^[a-z][\w\-]{2,7}$/i;
    out_put.innerHTML = label_ + reg.test(value);
});

30、批量使用正则完成密码验证

let pwd = document.createElement('input');
let output = document.createElement('div');
let label_ = '输出内容:';
output.innerHTML = label_;
document.body.appendChild(pwd);
document.body.appendChild(output);

pwd.addEventListener('keyup', ev => {
    const value = ev.target.value;
    const regs = [
        /^[a-z0-9]{5,10}/i,
        /[A-Z]/,
        /[0-9]/
    ]
    output.innerHTML = regs.every(item => item.test(value)) + '';
})

31、禁止贪婪匹配

let hd = 'hdddd';

// +? 表示按最少的进行匹配,非贪婪匹配
let reg = /hd+?/;
console.log(hd.match(reg));
// [ 'hd', index: 0, input: 'hdddd', groups: undefined ]

// 同理 *? , 总会以符合条件的最少次数来进行匹配
// {2,}? 禁止贪婪,总会以最少的次数匹配
// ? 表示匹配1次或者0次, ?? 表示禁止前面的?进行贪婪匹配,也就是匹配0次
let reg2 = /hd*?/;
console.log(hd.match(reg2));
// [ 'h', index: 0, input: 'hdddd', groups: undefined ]

32、标签替换的禁止贪婪使用

let dom = `
<main>
    <span>hou</span>
    <span>dunren.com</span>
    <span>hou</span>
</main>`;

// h4
// 非贪婪匹配
let reg = /<span>([\s\S]+?)<\/span>/ig;
console.log(dom.match(reg));
// [ '<span>hou</span>', '<span>dunren.com</span>', '<span>hou</span>' ]
let new_dom = dom.replace(reg, `<h4 style="color:red">$1</h4>`);
console.log(new_dom);
// <main>
//     <h4 style="color:red">hou</h4>
//     <h4 style="color:red">dunren.com</h4>
//     <h4 style="color:red">hou</h4>
// </main>


// 贪婪匹配的是整个
let reg1 = /<span>([\s\S]+)<\/span>/ig;
console.log(dom.match(reg1));
// [
//     '<span>hou</span>\n    <span>dunren.com</span>\n    <span>hou</span>'
// ]

33、使用matchAll完成全局匹配

let str = '<h1>后盾人</h1><h1>houdunren.com</h1><h1>baidu.com</h1>'
let reg = /<(h[1-6])>([\s\S]+?)<\/\1>/ig;
console.log(str.match(reg));
// [ '<h1>后盾人</h1>', '<h1>houdunren.com</h1>', '<h1>baidu.com</h1>' ]

console.log(str.matchAll(reg));
// Object [RegExp String Iterator] {}
let contents = [];
for (const iter of str.matchAll(reg)){
    console.log(iter);
    contents.push(iter);
}
// [
//     '<h1>后盾人</h1>',
//     'h1',
//     '后盾人',
//     index: 0,
//     input: '<h1>后盾人</h1><h1>houdunren.com</h1><h1>baidu.com</h1>',
//     groups: undefined
// ]
// [
//     '<h1>houdunren.com</h1>',
//     'h1',
//     'houdunren.com',
//     index: 12,
//     input: '<h1>后盾人</h1><h1>houdunren.com</h1><h1>baidu.com</h1>',
//     groups: undefined
// ]
// [
//     '<h1>baidu.com</h1>',
//     'h1',
//     'baidu.com',
//     index: 34,
//     input: '<h1>后盾人</h1><h1>houdunren.com</h1><h1>baidu.com</h1>',
//     groups: undefined
// ]

34、自定义方法matchAll

String.prototype.matchAll = function (reg){
    let res = this.match(reg);
    if (res){
        let str = this.replace(res[0], '^'.repeat(res[0].length));
        let match = str.matchAll(reg) || [];
        return [res, ...match];
    }
}

let hd = 'houdunren';
console.log(hd.matchAll(/u/i));
// [
// [ 'u', index: 2, input: 'houdunren', groups: undefined ],
// [ 'u', index: 4, input: 'ho^dunren', groups: undefined ]
// ]

35、使用exec完成全局匹配e

let hd = 'houdunren';
let reg = /u/gi;
// console.log(reg.lastIndex);
// console.log(reg.exec(hd));
// 0
//  [ 'u', index: 2, input: 'houdunren', groups: undefined ]

let res;
let result = [];
while ((res = reg.exec(hd))){
    result.push(res);
}
console.log(result);
// [
//     [ 'u', index: 2, input: 'houdunren', groups: undefined ],
//      [ 'u', index: 4, input: 'houdunren', groups: undefined ]
// ]

let str = '<h1>后盾人</h1><h1>houdunren.com</h1><h1>baidu.com</h1>'
function search(string, reg){
    let result = [];
    let res;
    // 如果reg表达式后面不用g的话会一直匹配第一个元素,永远也不会停止
    while ((res = reg.exec(string))){
        result.push(res);
    }
    return result;
}
let r = /<(h[1-6])>([\s\S]+?)<\/\1>/ig;
let res_ = search(str, r);
console.log(res_);

// [
//     '<h1>后盾人</h1>',
//     'h1',
//     '后盾人',
//     index: 0,
//     input: '<h1>后盾人</h1><h1>houdunren.com</h1><h1>baidu.com</h1>',
//     groups: undefined
// ],
// [
//     '<h1>houdunren.com</h1>',
//     'h1',
//     'houdunren.com',
//     index: 12,
//     input: '<h1>后盾人</h1><h1>houdunren.com</h1><h1>baidu.com</h1>',
//     groups: undefined
// ],
// [
//     '<h1>baidu.com</h1>',
//     'h1',
//     'baidu.com',
//     index: 34,
//     input: '<h1>后盾人</h1><h1>houdunren.com</h1><h1>baidu.com</h1>',
//     groups: undefined
// ]
// ]

36、字符串正则方法search与match

let hd = 'houdunren.com';

console.log(hd.search(/u/));
// 2
console.log(hd.match(/u/gi));
// [ 'u', 'u' ]


let urls = `
    https://baidu.com
    https://www.jindong.shop.cn
    https://zhihu.com
`;

let reg = /https?:\/\/(\w+\.)?(\w+\.)+(com|cn|org|cc)/ig;
console.log(urls.match(reg));
// [
//     'https://baidu.com',
//     'https://www.jindong.shop.cn',
//     'https://zhihu.com'
// ]

37、字符串正则方法matchAll与split

let urls = `
    https://baidu.com
    https://www.jindong.shop.cn
    https://zhihu.com
`;

let reg = /https?:\/\/(\w+\.)?(\w+\.)+(com|cn|org|cc)/ig;
let iterator = urls.matchAll(reg);
for (let iter of iterator){
    console.log(iter);
}
// [
//     'https://baidu.com',
//     undefined,
//     'baidu.',
//     'com',
//     index: 5,
//     input: '\n' +
// '    https://baidu.com\n' +
// '    https://www.jindong.shop.cn\n' +
// '    https://zhihu.com\n',
//     groups: undefined
// ]
// [
//     'https://www.jindong.shop.cn',
//     'www.',
//     'shop.',
//     'cn',
//     index: 27,
//     input: '\n' +
// '    https://baidu.com\n' +
// '    https://www.jindong.shop.cn\n' +
// '    https://zhihu.com\n',
//     groups: undefined
// ]
// [
//     'https://zhihu.com',
//     undefined,
//     'zhihu.',
//     'com',
//     index: 59,
//     input: '\n' +
// '    https://baidu.com\n' +
// '    https://www.jindong.shop.cn\n' +
// '    https://zhihu.com\n',
//     groups: undefined
// ]

let time1 = '2020-09-12';
let time2 = '2020/12/23';
let r = /[-\/]/;
console.log(time1.split(r));
// [ '2020', '09', '12' ]
console.log(time2.split(r));
// [ '2020', '12', '23' ]

38、$在正则中的使用

let time = '2020/12/12';
console.log(time.replace(/\//g, '-'));
// 2020-12-12

let num = '(010)99999999 (020)88888888';
let reg = /\((\d{3,4})\)(\d{7,8})/g;
console.log(num.match(reg));
// [ '(010)99999999', '(020)88888888' ]

// $1 , $2 表示原子组, 或者说是分好了的组
console.log(num.replace(reg, "$1-$2"));
// 010-99999999 020-88888888

// $& 表示匹配到的第一个元素,或者说就是 $0 (原身字符)

39、$&的使用

let str = '学习是一生的事情';
// 给学习加上超链接标签, $& 表示匹配的内容
let new_str = str.replace(/教育/, '<a href="#">$&</a>');
console.log(new_str);

40、原子组在替换中的使用技巧

let dom = `
    <a href="http://www.baidu.com">开源系统</a>
    <a id='l1' href="http://www.jindong.com">JD</a>
    <a href="https://zhihu.com">知乎</a>
    <h4>http://www.baidu.com</h4>
`
const reg = /(<a.*href=['"])(https?):\/\/(www\.)?(zhihu|jindong|baidu)/ig;
let new_dom = dom.replace(reg, (v, ...args)=>{
    args[1] += 's';
    args[3] = args[3] || 'www.';
    return args.splice(0, 5).join('');
})
console.log(new_dom);
// <a href="httpswww.baidu5.com">开源系统</a>
// <a id='l1' href="httpswww.jindong49.com">JD</a>
// <a href="httpsszhihu101.com">知乎</a>
// <h4>http://www.baidu.com</h4>

41、原子组别名

let str = `
<h1>hello</h1>
<span>alex</span>
<h2>world</h2>
`
// 将在分组里面像这写 (?<name>) 其中name表示在分组里面取得别名
const reg = /<(h[1-6])>(?<con>..*?)<\/\1>/ig;
// 然后可以通过 $<name> 的方式来获得分组里面的数据
console.log(str.replace(reg, '<h4>$<con></h4>'));
// <h4>hello</h4>
// <span>alex</span>
// <h4>world</h4>

42、使用原子组别名来优化正则

let dom = '<a href="https://www.baidu.com">baidu</a>>';
// 这里给正则娶了名字, 可以更加方便的获得自己想要的数据
const reg = /<a.*?href=(['"])(?<link>.*?)\1>(?<title>.*?)<\/a>/;
console.log(dom.match(reg));
// [
//     '<a href="https://www.baidu.com">baidu</a>',
//     '"',
//     'https://www.baidu.com',
//     'baidu',
//     index: 0,
//     input: '<a href="https://www.baidu.com">baidu</a>>',
//     groups: [Object: null prototype] {
//          link: 'https://www.baidu.com',
//          title: 'baidu'
// }
// ]

43、正则方法test

// 字符窜方法 match matchAll search replace
let email = '3410945446@qq.com';
let reg = /[\w-]+@(\w+\.)+(com|cn|cc)/;
console.log(reg.test(email));
// true

44、正则方法exec

// 字符窜方法 match matchAll search replace
let email = '3410945446@qq.com';
let reg = /[\w-]+@(\w+\.)+(com|cn|cc)/;
console.log(reg.exec(email));
// [
//     '3410945446@qq.com',
//     'qq.',
//     'com',
//     index: 0,
//     input: '3410945446@qq.com',
//     groups: undefined
// ]

// 正则表达式循环遍历方法
// let box = [];
// while (res = reg.exec(email)){
//     box.push(res);
// }

45、?=断言匹配

let str = '后盾人不断分享视频教程,学习后盾人教程提高编程能力';
let reg = /后盾人(?=教程)/g;
// 在这里可以把断言理解为判断条件, ?= 相当于if语句
let new_str = str.replace(reg, `<a href="https://www.baidu.com">$&</a>`);
console.log(new_str);
// 后盾人不断分享视频教程,学习<a href="https://www.baidu.com">后盾人</a>教程提高编程能力

46、使用断言规范价格

let lessons = `
    js,200元,300次
    php,200.00元,300次
    java,200元,300次
`;
// 断言并不会当作原子组来进行处理,也就说结果不会包含断言里面的内容,断言只是一个判断语句
let reg = /(\d+)(.00)?(?=元)/ig;
let new_lessons = lessons.replace(reg, (v, ...args)=>{
    console.log(args);
    args[1] = args[1] || '.00';
    return args.splice(0, 2).join('');
})
console.log(new_lessons);
    // [
    // '200', -->第一个分组
    //     undefined,  ---> 第二个分组
    //     8,   ---> 每个开始的索引值
    //     '\n    js,200元,300次\n    php,200.00元,300次\n    java,200元,300次\n'
    // ]
    // [
    // '200',
    //     '.00',
    //     26,
    //     '\n    js,200元,300次\n    php,200.00元,300次\n    java,200元,300次\n'
    // ]
    // [
    // '200',
    //     undefined,
    //     48,
    //     '\n    js,200元,300次\n    php,200.00元,300次\n    java,200元,300次\n'
    // ]

// js,200.00元,300次
// php,200.00元,300次
// java,200.00元,300次

47、?《= 断言匹配

let str = 'ewr789sdaf666';
// 表示前面是否满足这个条件
const reg = /(?<=ewr)\d+/i;
console.log(str.match(reg));
// [ '789', index: 3, input: 'ewr789sdaf666', groups: undefined ]


let link = '<a href="https://www.baidu.com">baidu</a>';
let reg_ = /(?<=href=(['"])).+(?=\1)/i;
console.log(link.match(reg_));
// [
//     'https://www.baidu.com',
//     '"',
//     index: 9,
//     input: '<a href="https://www.baidu.com">baidu</a>',
//     groups: undefined
// ]

48、使用断言模糊电话号码

let users = `
张三:13778775678
李四:18190198888
`
let reg = /(?<=\d{7})\d{4}/ig;
let new_users = users.replace(reg, _=>{
    return '*'.repeat(4);
})
console.log(new_users);
// 张三:1377877****
// 李四:1819019****

// 在这里和python不同的是, 字符串支持乘法复制元素,但是python可以支持
// 因此 javascript 里面出现的是 not a number
// 但是 python 里面可以得到 '****';
// js 必须调用repeat函数才可以实现
console.log('*' * 4);
// NaN
console.log('*'.repeat(4));
// ****

49、?!断言匹配

let url = 'houdunren2010hdcms';
// ?! 表示后面不是什么
// 下面这一句话表示以字符结尾并且后面不是数字的才符合条件
// 断言还只是一个判断语句而以,是虚的
let reg = /[a-z]+(?!\d+)$/i;
console.log(url.match(reg));
// [ 'hdcms', index: 13, input: 'houdunren2010hdcms', groups: undefined ]

50、断言限制用户名关键词语

let input = document.createElement('input');
let output = document.createElement('div');
output.innerHTML = '输出在这里:';
document.body.appendChild(input);
document.body.appendChild(output);

input.addEventListener('keyup', function (){
    // 输入框内不能有这一个单词或者词语
    // 同时包含5-6个字母
    // 一句话:包含5到6个字母但是不能有这个词语
    const reg =  /^(?!.*湘军.*)[a-z]{5,6}$/i;
    output.innerHTML = reg.test(this.value) + '';
});

51、?《!断言匹配

// ?<! 表示限制前面不是什么
let str = 'hello2020world';
// 这里表示匹配前部不是数字的字符串
let reg = /(?<!\d+)[a-z]+/i;
console.log(str.match(str));
// [
//     'hello2020world',
//     index: 0,
//     input: 'hello2020world',
//     groups: undefined
// ]

52、使用断言排除法同意数据

let url = `
<a href="https://www.huodunren.com/1.jpg">1.jpg</a>
<a href="https://oss.huodunren.com/2.jpg">2.jpg</a>
<a href="https://cdn.huodunren.com/3.jpg">3.jpg</a>
<a href="https://huodunren.com/4.jpg">4.jpg</a>`

const reg = /https:\/\/([a-z]+)?(?<!oss)\..+?(?=\/)/ig;
let new_url = url.replace(reg, v => {
    console.log(v);
    return 'https://oss.houdunren.com';
})
// https://www.huodunren.com
// https://cdn.huodunren.com
// https://huodunren.com


console.log(new_url);
// <a href="https://oss.houdunren.com/1.jpg">1.jpg</a>
// <a href="https://oss.huodunren.com/2.jpg">2.jpg</a>
// <a href="https://oss.houdunren.com/3.jpg">3.jpg</a>
// <a href="https://oss.houdunren.com/4.jpg">4.jpg</a>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值