文章目录
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);
非数字 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: branch01commit 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);
空的值也保存进去了!
[
‘’, ‘’,
‘’, ‘’,
‘’, ‘’,
‘’, ‘12321’,
‘12321’, ‘12321’,
‘12321’, ‘12321’,
‘12321’, ‘1232112312’,
‘1232112312’, ‘1232112312’
]
参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.02
Branch: branch01commit 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
。
[ ‘12321’, ‘12312’ ]
参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.03
Branch: branch01commit 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);
[ ‘12321’, ‘12312’, ‘33535’ ]
参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.04
Branch: branch01commit 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);
[ ‘12321’, ‘12312’, ‘33535’ ]
参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.05
Branch: branch01commit 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
分组(需要分组命名之后才会有!)
这里匹配到的是数组
[ ‘hello’, index: 0, input: ‘hello world’, groups: undefined ]
参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.06
Branch: branch01commit 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方法针对全局和非全局匹配的返回值是不一样的!
[ ‘hello’ ]
参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.07
Branch: branch01commit 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);
[ ‘hello’, index: 0, input: ‘hello world1231’, groups: undefined ]
参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.08
Branch: branch01commit 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);
[ ‘hello’ ]
参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.09
Branch: branch01commit 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);
[ ‘1231’ ]
参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.10
Branch: branch01commit description:a0.10(匹配数字,注意这里多加一个**
“\”
**进行转义)tag:a0.10
i
表示不区分大小写,打印结果一样!
let reg = new RegExp("\\d+","gi");
[ ‘1231’ ]
参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.11
Branch: branch01commit 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);
true
参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.12
Branch: branch01commit description:a0.12(正则方法 => test 、exce ——test使用)
tag:a0.12
let reg = /\d+/g;
let str = "fdasffdaf";
let res = reg.test(str);
console.log(res)
false
参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.13
Branch: branch01commit 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: branch01commit 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));
它可以连续调用,继续匹配!它只会返还一个,但是可以不停地执行。
[ ‘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: branch01commit 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);
[ ‘123’, ‘43’ ]
参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.16
Branch: branch01commit 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);
[ ‘123’, index: 5, input: ‘fdsaf123fda43’, groups: undefined ]
参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.17
Branch: branch01commit 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);
[ ‘a’, ‘b’, ‘c’, ‘d’ ]
参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.18
Branch: branch01commit 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);
[ ‘a’, ‘b’, ‘c’, ‘d’ ]
参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.19
Branch: branch01commit 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);
[ ‘a,’, ‘b,’, ‘c,’, ‘d’ ]
参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.20
Branch: branch01commit 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”
替换成一个“*”
,因为它找的是一个整体。
fdasf*dfaf*
参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.21
Branch: branch01commit 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)
fdasf***dfaf***
参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.22
Branch: branch01commit 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);
然后,*表达式在各种计算机语言或各种应用领域得到了广大的应用和发展,演变成为计算机技术森林中的一只形神美丽且声音动听的百 灵鸟。以上是关于*表达式的起源和发展的历史描述,如今*表达式在基于文本的编辑器和搜索工具中依然占据着一个非常重要的地位
参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.23
Branch: branch01commit 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);
然后,*表达式在各种*语言或各种应用领域得到了广大的应用和发展,演变成为*技术森林中的一只形神美丽且声音动听的百灵鸟。以上 是关于*表达式的起源和发展的历史描述,如今*表达式在基于文本的编辑器和搜索工具中依然占据着一个非常重要的地位
参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.24
Branch: branch01commit 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);
正则
计算机
计算机
正则
正则
然后,undefined表达式在各种undefined语言或各种应用领域得到了广大的应用和发展,演变成为undefined技术森林中的一只形神美丽 且声音动听的百灵鸟。以上是关于undefined表达式的起源和发展的历史描述,如今undefined表达式在基于文本的编辑器和搜索工具中依然占据着一个非常重要的地位
参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.25
Branch: branch01commit 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);
})
然后,**表达式在各种***语言或各种应用领域得到了广大的应用和发展,演变成为***技术森林中的一只形神美丽且声音动听的百灵鸟。以上是关于**表达式的起源和发展的历史描述,如今**表达式在基于文本的编辑器和搜索工具中依然占据着一个非常重要的地位
参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.26
Branch: branch01commit description:a0.26(字符串方法 => match、split、replace、search ——
replace
回调函数参数返回值替换字符)tag:a0.26
replace回调函数的参数:
-
匹配到的字符串;
-
分组里的内容;
-
匹配到字符串的索引值;
-
原来的字符串;
str.search(regexp) 方法执行正则表达式和 String
对象之间的一个搜索匹配。
search => 返还索引
// search
let str = "fdasf23dafs";
let reg = /\d/g;
let res = str.search(reg);
console.log(res);
5
参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.27
Branch: branch01commit 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);
-1
参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.28
Branch: branch01commit 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);
true
参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.29
Branch: branch01commit description:a0.29(元字符 =>
.
和*
使用)tag:a0.29
换行之后就匹配不上了!
let str = `<div>fdsa
fdsaf</div>`;
false
参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.30
Branch: branch01commit 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);
true
参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.31
Branch: branch01commit 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);
false
参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.32
Branch: branch01commit description:a0.32(元字符 =>
\w
和$
使用2)tag:a0.32
5. 字符集合
[xyz]
- 一个字符集合,也叫字符组。匹配集合中的任意一个字符。你可以使用连字符**
'-'
**指定一个范围 [xyz]
是一个反义或补充字符集,也叫反义字符组。也就是说,它匹配任意不在括号内的字符。你也可以通过使用连字符'-'
指定一个范围内的字符
[]
:字符集合
替换a
、b
字符
// []:字符集合
let str = "fdsafdafabfdsaf";
let reg = /a|b/g;
let res = str.replace(reg,"*");
console.log(res);
fds*fd*f**fds*f
参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.33
Branch: branch01commit description:a0.33(替换
a
、b
字符)tag:a0.33
还有其他的写法:用字符集合
注意在[]
里没有|
,直接隐含就有或者的意思
// []:字符集合
let str = "fdsafdafabfdsaf";
let reg = /[ab]/g
let res = str.replace(reg,"*");
console.log(res);
fds*fd*f**fds*f
参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.34
Branch: branch01commit description:a0.34(字符集合——替换
a
、b
字符)tag:a0.34
**把所有非 a 或者 b 的替换成 ***
^
放在字符集合内还是外是不一样的,放在外边是以…作为开头,如果放在里面就表示除了…以外,这里则是除了ab
以外的元素。
// 把所有非 a 或者 b 的替换成 *;
let str = "fdsafdafabfdsaf";
let reg = /[^ab]/g
let res = str.replace(reg,"*");
console.log(res);
***a**a*ab***a*
参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.35
Branch: branch01commit description:a0.35(字符集合——把所有非 a 或者 b 的替换成 *)
tag:a0.35
还可通过连接符,取一个范围
let str = "fdsafdSAaf4324abABCf4535dsaf";
let reg = /[a-z]/g;
let res = str.replace(reg,"*");
console.log(res);
******SA**4324**ABC*4535****
参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.36
Branch: branch01commit description:a0.36(字符集合——连接符的使用)
tag:a0.36
let str = "fdsafdSAaf4324abABCf4535dsaf";
let reg = /[a-zA-Z]/g
let res = str.replace(reg,"*");
console.log(res);
**********4324******4535****
参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.37
Branch: branch01commit description:a0.37(字符集合——连接符的使用2)
tag:a0.37
**注意:let reg = /[a-Z]/g;这样写是错误的,注意范围是根据ASCII
顺序来的!不能跳着顺序!必须按照从小到大
的顺序。
let str = "fdsafdSAaf4324abABCf4535dsaf";
let reg = /[0-9]/g
let res = str.replace(reg,"*");
console.log(res);
fdsafdSAaf****abABCf****dsaf
参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.38
Branch: branch01commit 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);
fdsafdSAaf43*4abABCf4535dsaf
参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.39
Branch: branch01commit 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}
n
和m
为正整数。前面的模式x
连续出现至少n
次,至多m
次时匹配
x{n,}
n
是一个正整数。前面的模式x
连续出现至少n
次时匹配
x*
- 匹配前面的模式
x 0
或多次
x+
- 匹配前面的模式
x 1
或多次
。等价于{1,}
x?
- 匹配前面的模式
x 0
或1 次
x|y
- 匹配
x
或y
{}:数量
匹配两个a
// {}数量;
let str = "abcaaabcdaafdsa";
let reg= /aa/g;
let res = str.replace(reg,"*");
console.log(res);
abc*abcd*fdsa
参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.40
Branch: branch01commit 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);
abc*abcd*fdsa
参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.41
Branch: branch01commit 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);
abc*bcdaafdsa
参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.42
Branch: branch01commit 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);
abc*bcd*fdsa
参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.43
Branch: branch01commit 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);
*bc*bcd*fds*
参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.44
Branch: branch01commit 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);
**b*c**b*c*d**f*d*s**
参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.45
Branch: branch01commit 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);
*fdsafabfdsaabfdsa
参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.46
Branch: branch01commit description:a0.46(():分组——
abab
替换成*
)tag:a0.46
取值
let str = "fdsabc123fdsfdsabc444";
let reg = /abc\d+/g;
let res = str.match(reg);
console.log(res);
[ ‘abc123’, ‘abc444’ ]
参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.47
Branch: branch01commit 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);
abc
参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.48
Branch: branch01commit 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
参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.49
Branch: branch01commit 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);
后面的分组会覆盖前面的分组!
abc 444
参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.50
Branch: branch01commit 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);
4/12/2019
参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.51
Branch: branch01commit 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);
4/1/2019
参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.52
Branch: branch01commit 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
]
参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.53
Branch: branch01commit 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);
[
‘abc123’,
‘abc’,
‘123’,
index: 3,
input: ‘fdsabc123fdsfdsabc444’,
groups: [Object: null prototype] { num: ‘123’ }
]
参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.54
Branch: branch01commit description:a0.54(():分组—— 命名分组)
tag:a0.54
(?:)
不捕获分组
let str = "fdsabc123fdsfdsabc444";
let reg = /(?:abc)(?<num>\d+)/;
let res = reg.exec(str);
console.log(res);
[
‘abc123’,
‘123’,
index: 3,
input: ‘fdsabc123fdsfdsabc444’,
groups: [Object: null prototype] { num: ‘123’ }
]
参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.55
Branch: branch01commit 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);
我们发现数字也没了,想办法别替换后面的数字!
苹果苹果苹果iphonenumber
参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.56
Branch: branch01commit 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);
苹果6苹果7苹果11iphonenumber
参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.57
Branch: branch01commit description:a0.57(():分组——正向肯定断言)
tag:a0.57
正向否定断言 => ?!
,即没有匹配到的进行替换(与以上相反)
let reg = /iphone(?!\d{1,2})/g // =换成!
let res = str.replace(reg,"苹果");
console.log(res);
iphone6iphone7iphone11苹果number
参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.58
Branch: branch01commit description:a0.58(():分组——正向否定断言)
tag:a0.58
实际就是正向断言
是放在后面,负向断言
放在前面。
负向肯定断言
let str = "10px20px30pxipx"; //px 转成 像素;
let reg = /\d{2}px/g;
let res = str.replace(reg,"像素");
console.log(res);
像素像素像素ipx
参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.59
Branch: branch01commit 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);
10像素20像素30像素ipx
参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.60
Branch: branch01commit description:a0.60(():分组——负向肯定断言)
tag:a0.60
负向否定断言 => ?<!
// 负向否定断言;
let str = "10px20px30pxipx"; //px 转成 像素;
let reg = /(?<!\d{2})px/g;
let res = str.replace(reg,"像素");
console.log(res);
10px20px30pxi像素
参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.61
Branch: branch01commit 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
-
unicode
,unicode
模式:匹配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);
*abcd efgfda
参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.62
Branch: branch01commit description:a0.62(匹配模式——默认单行匹配)
tag:a0.62
多行模式 => 匹配多行 => m
// 多行模式; 匹配多行
let str = `abcd
efgfda`;
let reg = /^/gm;
let res = str.replace(reg,"*");
console.log(res);
*abcd *efgfda
参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.63
Branch: branch01commit 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));
[ ‘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));
[ ‘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: branch01commit 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));
索引不连续获取不到,我们重新定义字符串
null
null
null
null
null
null
参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.65
Branch: branch01commit 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));
只要匹配项不连续,就获取失败!
[ ‘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: branch01commit 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
,这不满足需要了!
[ ‘is’, ‘is’ ]
参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.67
Branch: branch01commit 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);
[ ‘is’ ]
参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.68
Branch: branch01commit 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);
[ ‘is’, ‘is’ ]
参考:https://github.com/6xiaoDi/blog-Reg/tree/a0.69
Branch: branch01commit description:a0.69(匹配模式——边界全局匹配
is
)tag:a0.69
(后续待补充)