15分钟正则表达式快速上手(js)

1. 重点提炼

  • 正则的创建

  • 正则的匹配方法

  • 元字符

  • 字符集合

  • 边界

  • 分组

  • 反向引用

  • 数量词汇

  • 匹配模式


为什么会有正则表达式?

作用:字符串 => 查找、替换、验证、分割。


2. 字符串操作

  • 查找字符串中的数字
  • 正则如何如实现

需求: 查找字符串里的所有数字并放在数组中

isNaN() 函数用于检查其参数是否是非数字值。

返回值

如果 x 是特殊的非数字值 NaN(或者能被转换为这样的值),返回的值就是 true。如果 x 是其他值,则返回 false

isNaN(NaN);       // true
isNaN(undefined); // true
isNaN({});        // true
 
isNaN(true);      // false
isNaN(null);      // false
isNaN(37);        // false
 
// strings
isNaN("37");      // false: 可以被转换成数值37
isNaN("37.37");   // false: 可以被转换成数值37.37
isNaN("37,5");    // true
isNaN('123ABC');  // true:  parseInt("123ABC")的结果是 123, 但是Number("123ABC")结果是 NaN
isNaN("");        // false: 空字符串被转换成0
isNaN(" ");       // false: 包含空格的字符串被转换成0
 
// dates
isNaN(new Date());                // false
isNaN(new Date().toString());     // true
 
isNaN("blabla")   // true: "blabla"不能转换成数值
                  // 转换成数值失败, 返回NaN

实现需求:

let str = "afdafdf12321fdsafd12312fda33535";
// 得到的结果:[12321,12312];
function getNumber(str){
    let temp = "";
    let arr = [];
    for(let i=0;i<str.length;i++){
        if(!isNaN(str[i])){
            console.log("数字",str[i]);
        }else{
            console.log("非数字",str[i]);
        }
    }
}
let res =  getNumber(str);

image-20200529133102645

非数字 a
非数字 f
非数字 d
非数字 a
非数字 f
非数字 d
非数字 f
数字 1
数字 2
数字 3
数字 2
数字 1
非数字 f
非数字 d
非数字 s
非数字 a
非数字 f
非数字 d
数字 1
数字 2
数字 3
数字 1
数字 2
非数字 f
非数字 d
非数字 a
数字 3
数字 3
数字 5
数字 3
数字 5

参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.01
Branch: branch01

commit description:a0.01(查找字符串里的所有数字并放在数组中—判断是否是数字)

tag:a0.01


let str = "afdafdf12321fdsafd12312fda33535";
// 得到的结果:[12321,12312];
function getNumber(str){
    let temp = "";
    let arr = [];
    for(let i=0;i<str.length;i++){
        if(!isNaN(str[i])){
            // console.log("数字",str[i]);
            temp+=str[i];
        }else{
            // console.log("非数字",str[i]);
            arr.push(temp);
        }
    }
    console.log(arr);
}
let res =  getNumber(str);

空的值也保存进去了!

image-20200529133522878

[
‘’, ‘’,
‘’, ‘’,
‘’, ‘’,
‘’, ‘12321’,
‘12321’, ‘12321’,
‘12321’, ‘12321’,
‘12321’, ‘1232112312’,
‘1232112312’, ‘1232112312’
]

参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.02
Branch: branch01

commit description:a0.02(查找字符串里的所有数字并放在数组中—将数字追加进数组)

tag:a0.02


剔除空字符,以及每次pushtemp后,还需要清空temp,否则会累加字符。

let str = "afdafdf12321fdsafd12312fda33535";
// 得到的结果:[12321,12312];
function getNumber(str){
    let temp = "";
    let arr = [];
    for(let i=0;i<str.length;i++){
        if(!isNaN(str[i])){
            temp+=str[i];
        }else{
            if(temp !=""){
                arr.push(temp);
                temp = "";
            }
        }
    }
    console.log(arr);
}
let res =  getNumber(str);

但是末尾的数字没有返还!因为末尾的数字字符遍历完成后,后面没字符了,就结束了,没有往数组中push

image-20200529133837616

[ ‘12321’, ‘12312’ ]

参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.03
Branch: branch01

commit description:a0.03(查找字符串里的所有数字并放在数组中—末尾没有追加)

tag:a0.03


let str = "afdafdf12321fdsafd12312fda33535";
// 得到的结果:[12321,12312];
function getNumber(str){
    let temp = "";
    let arr = [];
    for(let i=0;i<str.length;i++){
        if(!isNaN(str[i])){
            temp+=str[i];
        }else{
            if(temp !=""){
                arr.push(temp);
                temp = "";
            }
        }
    }
    if(temp!=="")
        arr.push(temp);
    return arr;
}
let res =  getNumber(str);
console.log(res);

image-20200529134308198

[ ‘12321’, ‘12312’, ‘33535’ ]

参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.04
Branch: branch01

commit description:a0.04(完成查找字符串里的所有数字并放在数组中)

tag:a0.04


如果了解正则就会更简便。

/.../ 两个杠之间就是创建正则

\d 代表数字; **"+"一个或者多个;"g"**全局匹配(global简写)

let str = "afdafdf12321fdsafd12312fda33535";
let reg = /\d+/g;
let res =  str.match(reg); // match 匹配我们定义的正则规则
console.log(res);

image-20200529134308198

[ ‘12321’, ‘12312’, ‘33535’ ]

参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.05
Branch: branch01

commit description:a0.05(利用正则完成查找字符串里的所有数字并放在数组中)

tag:a0.05


3. 正则的匹配方法

字符串方法

  • match
  • search
  • replace
  • split

正则对象下的方法

  • test
  • exec

3.1 字面量创建

let mystr = "hello";
let reg = /hello/; // 完全匹配
let str = "hello world";
let res  = str.match(reg);
console.log(res);

匹配到的字符

index从索引0开始匹配到

input需要匹配的原字符串

groups分组(需要分组命名之后才会有!)

这里匹配到的是数组

image-20200529140052926

[ ‘hello’, index: 0, input: ‘hello world’, groups: undefined ]

参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.06
Branch: branch01

commit description:a0.06(字面量创建正则)

tag:a0.06


如果全局匹配

let mystr = "hello";
let reg = /hello/g;
let str = "hello world";
let res  = str.match(reg);
console.log(res);

输出匹配上的内容,就没上面的信息丰富了!因此match方法针对全局和非全局匹配的返回值是不一样的!

image-20200529140422025

[ ‘hello’ ]

参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.07
Branch: branch01

commit description:a0.07(字面量创建全局匹配正则)

tag:a0.07

let mystr = "hello";
let reg = /mystr/g;
......

注意在两个“/..../”放的都是字符串,在这里不能放入变量,即正则表达式中不能写变量,以上最终会转为字符串。 => 通过构造函数创建


3.2 构造函数创建

let mystr = "hello";
let str = "hello world1231";
let reg = new RegExp(mystr);
let res  = str.match(reg);
console.log(res);

image-20200529150215458

[ ‘hello’, index: 0, input: ‘hello world1231’, groups: undefined ]

参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.08
Branch: branch01

commit description:a0.08(构造函数创建正则)

tag:a0.08


全局匹配:

let mystr = "hello";
let str = "hello world1231";
let reg = new RegExp(mystr,"g");
let res  = str.match(reg);
console.log(res);

image-20200529140422025

[ ‘hello’ ]

参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.09
Branch: branch01

commit description:a0.09(构造函数创建全局匹配正则)

tag:a0.09


匹配数字,注意这里多加一个**“\”进行转义,否则就直接打印出来“d”**了

let mystr = "hello";
let str = "hello world1231";
let reg = new RegExp("\\d+","g");
let res  = str.match(reg);
console.log(res);

image-20200529150602923

[ ‘1231’ ]

参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.10
Branch: branch01

commit description:a0.10(匹配数字,注意这里多加一个**“\”**进行转义)

tag:a0.10


i表示不区分大小写,打印结果一样!

let reg = new RegExp("\\d+","gi");

image-20200529150602923

[ ‘1231’ ]

参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.11
Branch: branch01

commit description:a0.11(i表示不区分大小写,打印结果一样!)

tag:a0.11


3.3 正则方法 => test 、exce

test:返回是否匹配到(boolean)

let reg = /\d+/g;
let str = "fdasf23fdaf342";
let res =  reg.test(str);
console.log(res);

image-20200529151502500

true

参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.12
Branch: branch01

commit description:a0.12(正则方法 => test 、exce ——test使用)

tag:a0.12


let reg = /\d+/g;
let str = "fdasffdaf";
let res =  reg.test(str);
console.log(res)

image-20200529151545279

false

参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.13
Branch: branch01

commit description:a0.13(正则方法 => test 、exce ——test使用2)

tag:a0.13


exce: 执行

let reg = /\d+/g;
let str = "fdasf12fdaf121";
let res =  reg.exec(str)
console.log(res);

很像match函数,感觉貌似对“/g”不明感,只匹配了中间的“12”

[ ‘12’, index: 5, input: ‘fdasf12fdaf121’, groups: undefined ]

参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.14
Branch: branch01

commit description:a0.14(正则方法 => test 、exce ——exce使用)

tag:a0.14


结果不然!

let reg = /\d+/g;
let str = "fdasf12fdaf121";
// let res =  reg.exec(str)
// console.log(res);
console.log(reg.exec(str));
console.log(reg.exec(str));
console.log(reg.exec(str));

它可以连续调用,继续匹配!它只会返还一个,但是可以不停地执行。

image-20200529152639142

[ ‘12’, index: 5, input: ‘fdasf12fdaf121’, groups: undefined ]
[ ‘121’, index: 11, input: ‘fdasf12fdaf121’, groups: undefined ]
null

参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.15
Branch: branch01

commit description:a0.15(正则方法 => test 、exce ——exce使用2)

tag:a0.15


3.4 字符串方法 => match、split、replace、search

str.match(regexp) 方法检索返回一个字符串匹配正则表达式的结果。

let str = "fdsaf123fda43";
let reg = /\d+/g
let res =  str.match(reg);
console.log(res);

image-20200529153101833

[ ‘123’, ‘43’ ]

参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.16
Branch: branch01

commit description:a0.16(字符串方法 => match、split、replace、search ——match使用)

tag:a0.16


非全局匹配

let str = "fdsaf123fda43";
let reg = /\d+/
let res =  str.match(reg);
console.log(res);

image-20200529154427080

[ ‘123’, index: 5, input: ‘fdsaf123fda43’, groups: undefined ]

参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.17
Branch: branch01

commit description:a0.17(字符串方法 => match、split、replace、search ——match使用非全局匹配)

tag:a0.17


str.split([separator[, limit]]) 方法使用指定的分隔符字符串将一个String对象分割成子字符串数组,以一个指定的分割字串来决定每个拆分的位置。

separator 可以是一个字符串或正则表达式。 如果纯文本分隔符包含多个字符,则必须找到整个字符串来表示分割点。如果在str中省略或不出现分隔符,则返回的数组包含一个由整个字符串组成的元素。如果分隔符为空字符串,则将str原字符串中每个字符的数组形式返回。

limit 一个整数,限定返回的分割片段数量。

let str = "a,b,c,d";
let arr =  str.split(",");
console.log(arr);

image-20200529154707186

[ ‘a’, ‘b’, ‘c’, ‘d’ ]

参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.18
Branch: branch01

commit description:a0.18(字符串方法 => match、split、replace、search ——split使用)

tag:a0.18


但它也可接收正则:

let str = "a,b,c,d";
let reg = /,/g;
let arr =  str.split(reg);
console.log(arr);

image-20200529154707186

[ ‘a’, ‘b’, ‘c’, ‘d’ ]

参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.19
Branch: branch01

commit description:a0.19(字符串方法 => match、split、replace、search ——split使用-接收正则)

tag:a0.19


数字切割

let str = "a,543b,54c,54d";
let reg = /\d+/g;
let arr =  str.split(reg);
console.log(arr);

image-20200529155018840

[ ‘a,’, ‘b,’, ‘c,’, ‘d’ ]

参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.20
Branch: branch01

commit description:a0.20(字符串方法 => match、split、replace、search ——split使用-数字切割)

tag:a0.20


str.replace(regexp|substr, newSubStr|function) 方法返回一个由替换值(replacement)替换部分或所有的模式(pattern)匹配项后的新字符串。模式可以是一个字符串或者一个正则表达式,替换值可以是一个字符串或者一个每次匹配都要调用的回调函数。**如果pattern是字符串,则仅替换第一个匹配项。**原字符串不会改变。

参数

  • regexp(pattern)

    一个RegExp 对象或者其字面量。该正则所匹配的内容会被第二个参数的返回值替换掉。

  • substr(pattern)

    一个将被 newSubStr 替换的 字符串。其被视为一整个字符串,而不是一个正则表达式。仅第一个匹配项会被替换。

  • newSubStr (replacement)

    用于替换掉第一个参数在原字符串中的匹配部分的字符串。该字符串中可以内插一些特殊的变量名。参考下面的使用字符串作为参数

  • function (replacement)

    一个用来创建新子字符串的函数,该函数的返回值将替换掉第一个参数匹配到的结果。参考下面的指定一个函数作为参数

返回值

  • 一个部分或全部匹配由替代模式所取代的新的字符串。
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?"

替换

let str = "fdasf234dfaf342";// --->数字替换*
let reg = /\d+/g;
let newstr = str.replace(reg,"*");
console.log(newstr)

会发现一个问题把“234”替换成一个“*”,因为它找的是一个整体。

image-20200529161516400

fdasf*dfaf*

参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.21
Branch: branch01

commit description:a0.21(字符串方法 => match、split、replace、search ——replace使用)

tag:a0.21


去掉“+”

// 替换;
let str = "fdasf234dfaf342";// --->数字替换*
let reg = /\d/g;
let newstr = str.replace(reg,"*");
console.log(newstr)

image-20200529155257846

fdasf***dfaf***

参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.22
Branch: branch01

commit description:a0.22(字符串方法 => match、split、replace、search ——replace使用2)

tag:a0.22


需求:替换敏感词,如“正则”是敏感词,把正则 替换成"*"

// 替换敏感词;
let str = "然后,正则表达式在各种计算机语言或各种应用领域得到了广大的应用和发展,演变成为计算机技术森林中的一只形神美丽且声音动听的百灵鸟。以上是关于正则表达式的起源和发展的历史描述,如今正则表达式在基于文本的编辑器和搜索工具中依然占据着一个非常重要的地位";
// 把正则 替换成  "*";
let reg = /正则/g;
let newStr =  str.replace(reg,"*");
console.log(newStr);

image-20200529161923191

然后,*表达式在各种计算机语言或各种应用领域得到了广大的应用和发展,演变成为计算机技术森林中的一只形神美丽且声音动听的百 灵鸟。以上是关于*表达式的起源和发展的历史描述,如今*表达式在基于文本的编辑器和搜索工具中依然占据着一个非常重要的地位

参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.23
Branch: branch01

commit description:a0.23(字符串方法 => match、split、replace、search ——替换敏感词)

tag:a0.23


替换多个敏感词

敏感词要是有多个的话 => let reg = /正则|计算机/g;

// 替换敏感词;
let str = "然后,正则表达式在各种计算机语言或各种应用领域得到了广大的应用和发展,演变成为计算机技术森林中的一只形神美丽且声音动听的百灵鸟。以上是关于正则表达式的起源和发展的历史描述,如今正则表达式在基于文本的编辑器和搜索工具中依然占据着一个非常重要的地位";
// 把正则 替换成  "*";
// let reg = /正则/g;
let reg = /正则|计算机/g;  //敏感词要是有多个的话!
let newStr =  str.replace(reg,"*");
console.log(newStr);

image-20200529162315788

然后,*表达式在各种*语言或各种应用领域得到了广大的应用和发展,演变成为*技术森林中的一只形神美丽且声音动听的百灵鸟。以上 是关于*表达式的起源和发展的历史描述,如今*表达式在基于文本的编辑器和搜索工具中依然占据着一个非常重要的地位

参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.24
Branch: branch01

commit description:a0.24(字符串方法 => match、split、replace、search ——替换多个敏感词)

tag:a0.24


replace回调函数参数arg=> 会把符合规则的字符放入arg

// 替换敏感词;
let str = "然后,正则表达式在各种计算机语言或各种应用领域得到了广大的应用和发展,演变成为计算机技术森林中的一只形神美丽且声音动听的百灵鸟。以上是关于正则表达式的起源和发展的历史描述,如今正则表达式在基于文本的编辑器和搜索工具中依然占据着一个非常重要的地位";
// 把正则 替换成  "*";
// let reg = /正则/g;
let reg = /正则|计算机/g;  //敏感词要是有多个的话!
let newStr = str.replace(reg,function(arg){
    // 会把符合规则的字符放入arg
    console.log(arg);
})
console.log(newStr);

image-20200529163149736

正则
计算机
计算机
正则
正则
然后,undefined表达式在各种undefined语言或各种应用领域得到了广大的应用和发展,演变成为undefined技术森林中的一只形神美丽 且声音动听的百灵鸟。以上是关于undefined表达式的起源和发展的历史描述,如今undefined表达式在基于文本的编辑器和搜索工具中依然占据着一个非常重要的地位

参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.25
Branch: branch01

commit description:a0.25(字符串方法 => match、split、replace、search ——replace回调函数参数arg

tag:a0.25


根据敏感词个数替换成一定个数的“*” => return "*".repeat(arg.length)

let newStr = str.replace(reg,function(arg){
    return "*".repeat(arg.length);
})

image-20200529163442888

然后,**表达式在各种***语言或各种应用领域得到了广大的应用和发展,演变成为***技术森林中的一只形神美丽且声音动听的百灵鸟。以上是关于**表达式的起源和发展的历史描述,如今**表达式在基于文本的编辑器和搜索工具中依然占据着一个非常重要的地位

参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.26
Branch: branch01

commit description:a0.26(字符串方法 => match、split、replace、search ——replace回调函数参数返回值替换字符)

tag:a0.26


replace回调函数的参数

  1. 匹配到的字符串;

  2. 分组里的内容;

  3. 匹配到字符串的索引值;

  4. 原来的字符串;


str.search(regexp) 方法执行正则表达式和 String 对象之间的一个搜索匹配。

search => 返还索引

// search
let str = "fdasf23dafs";
let reg = /\d/g;
let res =  str.search(reg);
console.log(res);

image-20200529165126704

5

参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.27
Branch: branch01

commit description:a0.27(字符串方法 => match、split、replace、search ——search使用)

tag:a0.27


// search
let str = "fdasfdafs";
let reg = /\d/g;
let res =  str.search(reg);
console.log(res);

image-20200529165203585

-1

参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.28
Branch: branch01

commit description:a0.28(字符串方法 => match、split、replace、search ——search使用2)

tag:a0.28


4. 元字符

元字符 => 正则表达式中有特殊含义的非字母字符

=> . \* + $ ^ | \ ( ) [ ] { }

.

  • 匹配行结束符(\n \r \u2028\u2029)以外的任意单个字符
  • 字符集合(Character Sets) 中,. 将失去其特殊含义,表示的是原始值

\

  • 转义符,它有两层含义

  • 表示下一个具有特殊含义的字符为字面值

    • 表示下一个字符具有特殊含义(转义后的结果是元字符内约定的)

\d

  • 匹配任意一个阿拉伯数字的字符

\D

  • 匹配任意一个非阿拉伯数字的字符

\w

  • 匹配任意一个(字母、数字、下划线)的字符

\W

  • 匹配任意一个非(字母、数字、下划线)的字符

\s

  • 匹配一个空白符,包括空格、制表符、换页符、换行符和其他 Unicode空格

\S

  • 匹配一个非空白符

\t

  • 匹配一个水平制表符(tab

\r

  • 匹配一个回车符(carriage return

\n

  • 匹配一个换行符(linefeed

\v

  • 匹配一个垂直制表符(vertical tab

\f

  • 匹配一个换页符(form-feed

元字符正则里有特殊函数非字母字符

如:.*+$^|\()[]{};

.匹配行结束符(\n \r \u2028\u2029)以外的任意单个字符

“+”1个或者多个 ;“*” 0个或者多个;

注意</div>“/”需要转义,否则判定为正则的结束符号了!

let str = `<div>fdsafdsaf</div>`;
// 注意</div>中“/”需要转义,否则判定为正则的结束符号了!
let reg = /<div>.*<\/div>/g;
let res =  reg.test(str);
console.log(res);

image-20200529170500027

true

参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.29
Branch: branch01

commit description:a0.29(元字符 => .*使用)

tag:a0.29


换行之后就匹配不上了!

let str = `<div>fdsa
fdsaf</div>`;

image-20200529170627421

false

参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.30
Branch: branch01

commit description:a0.30(元字符 => .*使用2)

tag:a0.30


"^"以xx开头

“$”以xx结尾

\w : 数字、字母、下划线 (_)

let str = "abc434_3def";
// \w : 数字、字母、下划线 (_);
let reg = /^a\w+f$/g;
let res =  reg.test(str);
console.log(res);

image-20200529171910015

true

参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.31
Branch: branch01

commit description:a0.31(元字符 => \w$使用)

tag:a0.31


let str = "abc434_3defr";
// \w : 数字、字母、下划线 (_);
let reg = /^a\w+f$/g;
let res =  reg.test(str);
console.log(res);

image-20200529172000264

false

参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.32
Branch: branch01

commit description:a0.32(元字符 => \w$使用2)

tag:a0.32


5. 字符集合

[xyz]

  • 一个字符集合,也叫字符组。匹配集合中的任意一个字符。你可以使用连字符**'-'**指定一个范围
  • [xyz] 是一个反义或补充字符集,也叫反义字符组。也就是说,它匹配任意不在括号内的字符。你也可以通过使用连字符 '-' 指定一个范围内的字符

[]:字符集合

替换ab字符

// []:字符集合
let str = "fdsafdafabfdsaf";
let reg = /a|b/g;
let res =  str.replace(reg,"*");
console.log(res);

image-20200529173002757

fds*fd*f**fds*f

参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.33
Branch: branch01

commit description:a0.33(替换ab字符)

tag:a0.33


还有其他的写法:用字符集合

注意在[]里没有|,直接隐含就有或者的意思

// []:字符集合
let str = "fdsafdafabfdsaf";
let reg = /[ab]/g
let res =  str.replace(reg,"*");
console.log(res);

image-20200529173002757

fds*fd*f**fds*f

参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.34
Branch: branch01

commit description:a0.34(字符集合——替换ab字符)

tag:a0.34


**把所有非 a 或者 b 的替换成 ***

^放在字符集合内还是外是不一样的,放在外边以…作为开头,如果放在里面表示除了…以外,这里则是除了ab以外的元素。

// 把所有非 a 或者 b 的替换成 *;
let str = "fdsafdafabfdsaf";
let reg = /[^ab]/g
let res =  str.replace(reg,"*");
console.log(res);

image-20200529210414114

***a**a*ab***a*

参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.35
Branch: branch01

commit description:a0.35(字符集合——把所有非 a 或者 b 的替换成 *)

tag:a0.35


还可通过连接符,取一个范围

let str = "fdsafdSAaf4324abABCf4535dsaf";
let reg = /[a-z]/g;
let res =  str.replace(reg,"*");
console.log(res);

image-20200529211614312

******SA**4324**ABC*4535****

参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.36
Branch: branch01

commit description:a0.36(字符集合——连接符的使用)

tag:a0.36


let str = "fdsafdSAaf4324abABCf4535dsaf";
let reg = /[a-zA-Z]/g
let res =  str.replace(reg,"*");
console.log(res);

image-20200529211741649

**********4324******4535****

参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.37
Branch: branch01

commit description:a0.37(字符集合——连接符的使用2)

tag:a0.37


**注意:let reg = /[a-Z]/g;这样写是错误的,注意范围是根据ASCII顺序来的!不能跳着顺序!必须按照从小到大的顺序。

image-20200529213017013

image-20201029092704656

image-20200529213101721


let str = "fdsafdSAaf4324abABCf4535dsaf";
let reg = /[0-9]/g
let res =  str.replace(reg,"*");
console.log(res);

image-20200529220307580

fdsafdSAaf****abABCf****dsaf

参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.38
Branch: branch01

commit description:a0.38(字符集合——连接符的使用3)

tag:a0.38


注意这里不会匹配0~20,而是0、1、2后面那个只能是或0!

let str = "fdsafdSAaf4324abABCf4535dsaf";
let reg = /[0-20]/g
let res =  str.replace(reg,"*");
console.log(res);

image-20200529220631518

fdsafdSAaf43*4abABCf4535dsaf

参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.39
Branch: branch01

commit description:a0.39(字符集合——匹配0~20失败)

tag:a0.39


等同关系:

. ===> [^\n\r\u2028\u2029]
\d ===> [0-9];
\w ===>[a-zA-Z0-9_]; "数组、字母、下划线"
匹配20 ===> [12]0 "第一位是1或者2,第二位是0"

6. 数量词汇

x{n}

  • n是一个正整数。前面的模式 x连续出现 n次时匹配

x{n,m}

  • nm正整数。前面的模式 x 连续出现至少 n次,至多 m 次时匹配

x{n,}

  • n 是一个正整数。前面的模式x 连续出现至少 n 次时匹配

x*

  • 匹配前面的模式 x 0多次

x+

  • 匹配前面的模式 x 1多次。等价于 {1,}

x?

  • 匹配前面的模式 x 01 次

x|y

  • 匹配xy

{}:数量

匹配两个a

// {}数量;
let str = "abcaaabcdaafdsa";
let reg= /aa/g;
let res =  str.replace(reg,"*");
console.log(res);

image-20200530115151504

abc*abcd*fdsa

参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.40
Branch: branch01

commit description:a0.40(匹配两个a)

tag:a0.40


还要另外一种写法,匹配两个a

let str = "abcaaabcdaafdsa";
let reg= /a{2}/g; // 指定a出现两次
let res =  str.replace(reg,"*");
console.log(res);

image-20200530115151504

abc*abcd*fdsa

参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.41
Branch: branch01

commit description:a0.41(数量词汇——匹配两个a)

tag:a0.41


指定a出现3

// {}数量;
let str = "abcaaabcdaafdsa";
let reg= /a{3}/g; // 指定a出现3次
let res =  str.replace(reg,"*");
console.log(res);

image-20200530115430010

abc*bcdaafdsa

参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.42
Branch: branch01

commit description:a0.42(数量词汇——指定a出现3次)

tag:a0.42


指定a出现2次或3

let str = "abcaaabcdaafdsa";
let reg= /a{2,3}/g; // 指定a出现2次或3次
let res =  str.replace(reg,"*");
console.log(res);

image-20200530115710846

abc*bcd*fdsa

参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.43
Branch: branch01

commit description:a0.43(数量词汇——指定a出现2次或3次)

tag:a0.43


指定a出现1次或3

let str = "abcaaabcdaafdsa";
let reg= /a{1,3}/g; // 指定1次到3次
let res =  str.replace(reg,"*");
console.log(res);

image-20200530115948393

*bc*bcd*fds*

参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.44
Branch: branch01

commit description:a0.44(数量词汇——指定a出现1次或3次)

tag:a0.44


指定a出现0次或

let str = "abcaaabcdaafdsa";
let reg = /a{0,}/g // 指定0次或多次
let res =  str.replace(reg,"*");
console.log(res);

image-20200530120301690

**b*c**b*c*d**f*d*s**

参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.45
Branch: branch01

commit description:a0.45(数量词汇——指定a出现0次或次)

tag:a0.45


* ===> {0,}   等同于0次或多次
+ ==>{1,}     等同于1次或多次
? ===> {0,1};  等同于0次或1

7. 分组

(子项)

  • 可以使用 () 对表达式进行分组,类似数学中分组,也称为子项
  • 索引分组
  • 命名分组
    • (?<name>...)
    • **groups**属性
  • 捕获匹配
    • 具有捕获(capturing)特性,即会把匹配结果保存到(子项结果)中
    • (x)
  • 非捕获匹配
    • 不具有捕获(capturing)特性,即不会把匹配结果保存到(子项结果)中
    • (?:x)
  • 零宽断言/预查(Assertions
    • 用于指定查找在某些内容(但并不包括这些内容)之前之后的内容
    • 正向零宽断言/预查
      • 肯定
        • (?=pattern)
      • 否定
        • (?!pattern)
    • 负向零宽断言/预查(注意:ES2018新增)
      • 肯定
        • (?<=pattern)
      • 否定
        • (?<!patten)
  • 捕获与零宽断言的区别
    • 捕获:匹配的内容出现在结果中但不出现在子项结果中
    • 零宽断言:完全不会出现在结果

():分组

=> abab替换*

/ab{2}/g 就成abb

let str = "ababfdsafabfdsaabfdsa";
let reg = /(ab){2}/g; // 替换两个ab
let res =  str.replace(reg,"*");
console.log(res);

image-20200530121441515

*fdsafabfdsaabfdsa

参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.46
Branch: branch01

commit description:a0.46(():分组—— abab替换*

tag:a0.46


取值

let str = "fdsabc123fdsfdsabc444";
let reg = /abc\d+/g;
let res =  str.match(reg);
console.log(res);

image-20200530122640245

[ ‘abc123’, ‘abc444’ ]

参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.47
Branch: branch01

commit description:a0.47(():分组—— 取值)

tag:a0.47


let str = "fdsabc123fdsfds444";
let reg = /(abc)(\d+)/g; // 分组取数据
let res =  str.match(reg);
// console.log(res);
let $1 = RegExp.$1;
console.log(RegExp.$1);

image-20200530123048745

abc

参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.48
Branch: branch01

commit description:a0.48(():分组—— 取值)

tag:a0.48


注意不要如下这种使用,因为RegExp它是全局变量,会存在相互引用关系,建议用变量接收一下!

let str = "fdsabc123fdsfds444";
let reg = /(abc)(\d+)/g; // 分组取数据
let res =  str.match(reg);
console.log(RegExp.$1);
console.log(RegExp.$2);

abc
123

let str = "fdsabc123fdsfds444";
let reg = /(abc)(\d+)/g; // 分组取数据
let res =  str.match(reg);
let $1 = RegExp.$1; 
let $2  = RegExp.$2;
console.log($1,$2);

abc 123

image-20200530123549666

参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.49
Branch: branch01

commit description:a0.49(():分组—— 取值)

tag:a0.49


let str = "fdsabc123fdsfdsabc444";
let reg = /(abc)(\d+)/g; // 分组取数据
let res =  str.match(reg);
let $1 = RegExp.$1;
let $2  = RegExp.$2;
console.log($1,$2);

后面的分组会覆盖前面的分组!

image-20200530123739413

abc 444

参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.50
Branch: branch01

commit description:a0.50(():分组—— 后面的分组会覆盖前面的分组)

tag:a0.50


dollar符号,引用之前的分组的对应关系替换即可。

let str = "2019-12-4";  //  -->4/12/2019;
let reg = /(\d{4})-(\d{2})-(\d{1,2})/g;
let res =  str.replace(reg,"$3/$2/$1");
console.log(res);

image-20200530125335937

4/12/2019

参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.51
Branch: branch01

commit description:a0.51(():分组—— 日期转换)

tag:a0.51


再完善: 日期也可为单个数字 => let reg = /(\d{4})-(\d{1,2})-(\d{1,2})/g;

let str = "2019-1-4";
let reg = /(\d{4})-(\d{1,2})-(\d{1,2})/g;
let res =  str.replace(reg,"$3/$2/$1");
console.log(res);

image-20200530123933199

4/1/2019

参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.52
Branch: branch01

commit description:a0.52(():分组—— 完善日期转换)

tag:a0.52


命名分组?<name> name自定义

(xxx) <默认>捕获分组(?:)不捕获分组

let str = "fdsabc123fdsfdsabc444";
let reg = /(abc)(\d+)/;
let res =  str.match(reg);
console.log(res);

[
‘abc123’,
‘abc’,
‘123’,
index: 3,
input: ‘fdsabc123fdsfdsabc444’,
groups: undefined
]

image-20200530130121295

参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.53
Branch: branch01

commit description:a0.53(():分组—— 分组)

tag:a0.53


**groups:**分组,作用就是命名分组!

里面第一个是匹配的字符,后两个是分了两组,如果有命名分组就会放在groups:num里面:

let str = "fdsabc123fdsfdsabc444";
let reg = /(abc)(?<num>\d+)/;
let res =  reg.exec(str);
console.log(res);

image-20200530130552088

[
‘abc123’,
‘abc’,
‘123’,
index: 3,
input: ‘fdsabc123fdsfdsabc444’,
groups: [Object: null prototype] { num: ‘123’ }
]

参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.54
Branch: branch01

commit description:a0.54(():分组—— 命名分组)

tag:a0.54


(?:)不捕获分组

let str = "fdsabc123fdsfdsabc444";
let reg = /(?:abc)(?<num>\d+)/;
let res =  reg.exec(str);
console.log(res);

image-20200530130956062

[
‘abc123’,
‘123’,
index: 3,
input: ‘fdsabc123fdsfdsabc444’,
groups: [Object: null prototype] { num: ‘123’ }
]

参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.55
Branch: branch01

commit description:a0.55(():分组—— 不捕获分组)

tag:a0.55


掌握一下正则的新属性:es2018 -->es9

零宽断言(分正向和负向) => 正向负向里又分肯定和否定

  • \w+(?=ing) 匹配以ing结尾的多个字符(不包括ing)
  • \w+(?!ing) 匹配不是ing结尾的多个字符

  • (?<=re)\w+ 匹配以re开头的多个字符(不包括re)
  • (?<!re)\w+ 匹配不是re开头的多个字符

  • (?<=\s)\d+(?=\s) 匹配两边是空白符的数字,不包括空白符

以下是正向肯定断言 => 匹配到的进行替换

let str = "iphone6iphone7iphone11iphonenumber";
// iphone-->苹果
let reg = /iphone\d{1,2}/g
let res  = str.replace(reg,"苹果");
console.log(res);

我们发现数字也没了,想办法别替换后面的数字!

image-20200530131629704

苹果苹果苹果iphonenumber

参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.56
Branch: branch01

commit description:a0.56(():分组—— replace使用)

tag:a0.56


不替换iphone后的数字

?=表示可能存在后面的内容,即保留下来

let str = "iphone6iphone7iphone11iphonenumber";
// iphone-->苹果
// ?= 表示可能存在后面的内容
let reg = /iphone(?=\d{1,2})/g
let res  = str.replace(reg,"苹果");
console.log(res);

image-20200530132356530

苹果6苹果7苹果11iphonenumber

参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.57
Branch: branch01

commit description:a0.57(():分组——正向肯定断言)

tag:a0.57


正向否定断言 => ?! ,即没有匹配到的进行替换(与以上相反)

let reg = /iphone(?!\d{1,2})/g // =换成!
let res  = str.replace(reg,"苹果");
console.log(res);

image-20200530154819741

iphone6iphone7iphone11苹果number

参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.58
Branch: branch01

commit description:a0.58(():分组——正向否定断言)

tag:a0.58


实际就是正向断言是放在后面,负向断言放在前面。

负向肯定断言

let str = "10px20px30pxipx";  //px 转成 像素;
let reg = /\d{2}px/g;
let res = str.replace(reg,"像素");
console.log(res);

image-20200530155440671

像素像素像素ipx

参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.59
Branch: branch01

commit description:a0.59(():分组——px 转成 像素)

tag:a0.59


只需要替换px,我们可以对前面下断言!假设它有! => ?<=

let str = "10px20px30pxipx";  //px 转成 像素;
// let reg = /\d{2}px/g;
let reg = /(?<=\d{2})px/g;
let res = str.replace(reg,"像素");
console.log(res);

image-20200530155815454

10像素20像素30像素ipx

参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.60
Branch: branch01

commit description:a0.60(():分组——负向肯定断言)

tag:a0.60


负向否定断言 => ?<!

// 负向否定断言;
let str = "10px20px30pxipx";  //px 转成 像素;
let reg = /(?<!\d{2})px/g;
let res = str.replace(reg,"像素");
console.log(res);

image-20200530160120296

10px20px30pxi像素

参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.61
Branch: branch01

commit description:a0.61(():分组——负向否定断言)

tag:a0.61


8. 边界

^

  • 匹配输入开始。如果多行(multiline)标志被设为 true,该字符也会匹配一个断行(line break)符后的开始处

$

  • 匹配输入结尾。如果多行(multiline)标志被设为 true,该字符也会匹配一个断行(line break)符的前的结尾处

\b

  • 匹配一个零宽单词边界(zero-width word boundary

\B

  • 匹配一个非零宽单词边界(zero-width word boundary

9. 反向引用

\n

  • 这里的 n 表示的是一个变量,值为一个数字,指向正则表达式中第 n 个括号(从左开始数)中匹配的子字符串

10. 匹配模式

g

  • global全局模式:找到所有匹配,而不是在第一个匹配后停止

i

  • ignore忽略大小写模式:匹配不区分大小写

m

  • multiple多行模式:将开始和结束字符(^和$)视为在多行上工作,而不只是匹配整个输入字符串的最开始和最末尾处

s

  • dotAll / singleline模式. 可以匹配换行符

u

  • unicodeunicode模式:匹配unicode字符集

     console.log(/^.$/.test("\uD842\uDFB7"));
     console.log(/^.$/u.test("\uD842\uDFB7"));
    

y

  • sticky粘性模式:匹配正则中lastIndex属性指定位置的字符,并且如果没有匹配也不尝试从任何后续的索引中进行匹配

正则工具 http://regexper.com


let str = `abcd
efgfda`;
let reg = /^/g;
let res  = str.replace(reg,"*");
console.log(res);

image-20200530160433366

*abcd efgfda

参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.62
Branch: branch01

commit description:a0.62(匹配模式——默认单行匹配)

tag:a0.62


多行模式 => 匹配多行 => m

// 多行模式; 匹配多行
let str = `abcd
efgfda`;
let reg = /^/gm;
let res  = str.replace(reg,"*");
console.log(res);

image-20200530160457376

*abcd *efgfda

参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.63
Branch: branch01

commit description:a0.63(匹配模式——多行模式)

tag:a0.63


非粘性模式:

let str = "fda244dfa12sf";
let reg =  /\d/g;
console.log(reg.exec(str));
console.log(reg.exec(str));
console.log(reg.exec(str));
console.log(reg.exec(str));

image-20200530160647874

[ ‘2’, index: 3, input: ‘fda244dfa12sf’, groups: undefined ]
[ ‘4’, index: 4, input: ‘fda244dfa12sf’, groups: undefined ]
[ ‘4’, index: 5, input: ‘fda244dfa12sf’, groups: undefined ]
[ ‘1’, index: 9, input: ‘fda244dfa12sf’, groups: undefined ]

let str = "fda244dfa12sf";
let reg =  /\d/g;
console.log(reg.exec(str));
console.log(reg.exec(str));
console.log(reg.exec(str));
console.log(reg.exec(str));
console.log(reg.exec(str));
console.log(reg.exec(str));

image-20200530160945215

[ ‘2’, index: 3, input: ‘fda244dfa12sf’, groups: undefined ]
[ ‘4’, index: 4, input: ‘fda244dfa12sf’, groups: undefined ]
[ ‘4’, index: 5, input: ‘fda244dfa12sf’, groups: undefined ]
[ ‘1’, index: 9, input: ‘fda244dfa12sf’, groups: undefined ]
[ ‘2’, index: 10, input: ‘fda244dfa12sf’, groups: undefined ]
null

参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.64
Branch: branch01

commit description:a0.64(匹配模式——默认非粘性模式)

tag:a0.64


粘性模式:索引必须连续

let str = "fda244dfa12sf";
let reg =  /\d/gy;
console.log(reg.exec(str));
console.log(reg.exec(str));
console.log(reg.exec(str));
console.log(reg.exec(str));
console.log(reg.exec(str));
console.log(reg.exec(str));

索引不连续获取不到,我们重新定义字符串

image-20200530161050556

null
null
null
null
null
null

参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.65
Branch: branch01

commit description:a0.65(匹配模式——索引不连续获取不到)

tag:a0.65


let str = "244dfa12sf";
let reg =  /\d/gy;
console.log(reg.exec(str));
console.log(reg.exec(str));
console.log(reg.exec(str));
console.log(reg.exec(str));
console.log(reg.exec(str));
console.log(reg.exec(str));

只要匹配项不连续,就获取失败!

image-20200530161215304

[ ‘2’, index: 0, input: ‘244dfa12sf’, groups: undefined ]
[ ‘4’, index: 1, input: ‘244dfa12sf’, groups: undefined ]
[ ‘4’, index: 2, input: ‘244dfa12sf’, groups: undefined ]
null
[ ‘2’, index: 0, input: ‘244dfa12sf’, groups: undefined ]
[ ‘4’, index: 1, input: ‘244dfa12sf’, groups: undefined ]

参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.66
Branch: branch01

commit description:a0.66(匹配模式——只要匹配项不连续,就获取失败!)

tag:a0.66


\b: 边界符号边界即为 \w (数字、字母、下划线)

let str = "this is a knife";
let reg = /is/g;
let res =  str.match(reg);
console.log(res);

我们只想要空格后的is,这不满足需要了!

image-20200530161737639

[ ‘is’, ‘is’ ]

参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.67
Branch: branch01

commit description:a0.67(匹配模式——全局匹配is

tag:a0.67


let str = "this is a knife";
let reg = /\bis\b/g;
let res =  str.match(reg);
console.log(res);

image-20200530161838994

[ ‘is’ ]

参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.68
Branch: branch01

commit description:a0.68(匹配模式——边界全局匹配is

tag:a0.68


dollar符也相当于边界符号:

let str = "th$is is a knife";
let reg = /\bis\b/g;
let res =  str.match(reg);
console.log(res);

image-20200530161737639

[ ‘is’, ‘is’ ]

参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.69
Branch: branch01

commit description:a0.69(匹配模式——边界全局匹配is

tag:a0.69



(后续待补充)
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值