思考题一:字符串拼接规则
字符串拼接规则 外双内单 外单内双
var str = "我是一名"牛逼"的程序员"; // 为什么报语法错误?
document.write(str);
根本原因:javascript先解析的是正常的语法
解析过程 =》 "我是一名" "的程序员" 这是字符串的语法; 然后 中间是变量
把语法分析完毕之后,才会做文本输出。当做文本输出的时候,发现变量与字符串中间没有加号,这时候才会报语法错误
改错一:使用转义字符,改变一下
var str = "我是一名\"牛逼\"的程序员";
document.write(str); // 结果:"我是一名"牛逼"的程序员"
var str = "我是一名\\牛逼\\的程序员";
document.write(str); // 结果:"我是一名\牛逼\的程序员"
改错二:
var str = "我是一名\n牛逼\n的程序员";
document.write(str); // 我是一名 牛逼 的程序员
问题:页面为什么会识别为一个空格?
因为: \n \r \t 这是给编辑系统用的,不是给html用的
html实体:用于处理html当中特殊的字符,如: > > < < 为什么没有 \n \r \t 呢??
因为 \n \r \t 都是编辑的时候用的,咱们的编辑器如vscode,每次换行,
在编辑器系统软件内部其实都有一个换行 \n ,这是系统级别的
而html页面是纯文本的,编译以后文本显示出来的,所以html不可能识别 \n \r \t
有空格的原因:是因为 \n 占用了字符
思考二:不允许字符串多行
var str = '<h1>我是小白</h1>
<h2>从事前端编程</h2>
<h3>目标高级前端</h3>'; // 这样写系统会报错
/*
根本原因:javascript 默认不允许字符串多行 【牢记】
*/
改错一:字符串拼接 【有点傻不推荐】
var str = '<h1>我是小白</h1>'+
'<h2>从事前端编程</h2>'+
'<h3>目标高级前端</h3>';
var wrap = document.getElementsByTagName('div')[0];
wrap.innerHTML = str;
改错二:使用转义符号,把回车和换行进行转义为空格 ( 把标签左右的空白转义为空格 )
控制台打印结果:
<h1>我是小白</h1> <h2> 从事前端编程</h2> <h3> 目标高级前端</>
var str = '<h1>我是小白</h1>\
<h2>从事前端编程</h2>\
<h3>目标高级前端</h3>';
var wrap = document.getElementsByTagName('div')[0];
wrap.innerHTML = str;
改错三:使用模板拼接 【推荐】
<body>
<div id="div" style="background:green;"></div>
<script type="text/template" id="div2">
<div>数据:{{data}}</div>
<div>年龄:{{age}}</div>
<div>姓名:{{name}}</div>
</script>
<script type="text/javascript">
var div = document.querySelector('#div');
var div2 = document.getElementById('div2');
var data = { data: "123", name: "csdn", age: "xxoo" };
div.innerHTML = div2.innerHTML.replace(/\{\{([\s\S]+?)\}\}/g, ($0, $1) => {
return data[$1] || '';
});
</script>
</body>
转义符号 和 转义字符的区别
-
转义符号:
\
-
转义字符:
\字符
-
特殊的转义字符:
\n
、\r
、\t
,它们有特定的功能\n :表示换行 \t:表示tab键,代表4个空格
第 1 章:正则表达式
1.1 含义
含义:正则表达式是一些用来匹配和处理文本的字符串。它有两种基本用途:搜索和替换
给定一个正则表达式,它要么匹配一些文本(进行一次搜索),要么匹配并替换一些文本(进行一次替换)
1.2 创建方式
方式一:构造函数模式
实例化一个正则对象 形如:var obj = new Object()
;有两个参数:new RegExp()
参数1:正则表达式
参数2:一些修饰符,如: i (忽略大小写) g(全局) m(多行匹配)
-
只能处理字符串
-
它是一个规则:可以验证字符串是否符合某个规则(test),
也可以把字符串中符合规则的内容捕获到(exec / match…)
//=> 在字符串中,两个斜杠才代表斜杠的意思!!!
let reg2 = new RegExp("\\d+");
//=>例如:\n 表示换行 ;\\n 代表 \n本身
var reg = new RegExp('test'),
str = 'This is a test';
console.log(reg.test(str)); // true
var reg = new RegExp('Test'),
str = 'This is a test';
console.log(reg.test(str)); // false
var reg = new RegExp('est'),
str = 'This is a test';
console.log(reg.test(str)); // true
/*
表达的含义:以正则表达式为规则,检验字符串str中是否 包含 指定的字符串片段
注意:要求是连续的字符串片段 对于大小写敏感
*/
修改一:添加修饰符 i ( ingore case ),忽略大小写
var reg = new RegExp('Test', 'i'),
str = 'This is a test';
console.log(reg.test(str)); // true
//=>拓展:match() 方法可在字符串内检索指定的值,或找到一个或多个正则表达式的匹配
var reg1 = new RegExp('Test', 'i'), // 忽略大小写
str1 = 'This is a test. Test is important';
console.log(str1.match(reg1));
// ["test", index: 10, input: "This is a test. Test is important", groups: undefined]
var reg2 = new RegExp('Test', 'ig'), // 忽略大小写且全局匹配
str2 = 'This is a test. Test is important';
console.log(str2.match(reg2)); // ["test", "Test"]
var reg = new RegExp('^Test', 'igm'),// 忽略大小写且全局匹配且多行匹配 匹配以Test开头的
str = 'This is a test. \nTest is important';
console.log(str.match(reg)); // ["Test"]
方式二:字面量创建方式
两个斜杆之间包起来的,都是用来描述正则规则的元字符
var reg =/test/,
str = 'This is a test';
console.log(reg.test(str)); // true
var reg =/Test/,
str = 'This is a test';
console.log(reg.test(str)); // false
var reg =/est/,
str = 'This is a test';
console.log(reg.test(str)); // true
var reg =/Test/i,
str = 'This is a test';
console.log(reg.test(str)); // true
//=>拓展:match() 方法可在字符串内检索指定的值,或找到一个或多个正则表达式的匹配
var reg1 =/Test/i, // 忽略大小写
str1 = 'This is a test. Test is important';
console.log(str1.match(reg1));
// ["test", index: 10, input: "This is a test. Test is important", groups: undefined]
var reg2 =/Test/ig, // 忽略大小写且全局匹配
str2 = 'This is a test. Test is important';
console.log(str2.match(reg2)); // ["test", "Test"]
var reg3 =/^Test/igm,// 忽略大小写且全局匹配且多行匹配 匹配以Test开头的
str3 = 'This is a test. \nTest is important';
console.log(str3.match(reg3)); // ["Test"]
两种创建方式的区别
//=> 构造函数因为传递的是字符串,\需要写两个才代表斜杠
let reg = /\d+/g;
reg = new RegExp("\\d+","g");
//=> 正则表达式中的部分内容是变量存储的值
//=> 1.两个斜杠中间包起来的都是元字符(如果正则中要包含某个变量的值,则不能使用字面量方式创建)
//=>2.这种情况只能使用构造函数方式(因为它传递的规则是字符串,只有这样才能进行字符串拼接)
let type1 = "lisi";
reg1 = new RegExp("^@"+type1+"@$");
console.log(reg1.test("@lisi@"));//=>true
/*
思考正则匹配的规则:【匹配成功的不会再倒回去匹配】 而是连续的进行匹配
例如: 123 匹配成功 就不会 再去匹配 234 而是接着找 4ds 没匹配上 接着往下找...
找到 p34 没匹配成功 但是 345匹配成功了 【前面没匹配成功,才会倒回去接着匹配】
*/
var str = '1234dsf3rp345df35q',
reg = /[1234567890][1234567890][1234567890]/g;
console.log(str.match(reg)); // ["123", "345"]
var str = 'wxyz',
reg = /[wx][xy][z]/g;
console.log(str.match(reg)); // ["xyz"]
var str = 'we24DsaD34',
reg = /[0-9][A-Z][a-z]/g;
console.log(str.match(reg)); // ["4Ds"]
/*
找4位字符串
第一位:不是0 [^0]
第二位:0-9之间的数字 或者 A-Z 或者 a-z
第三位:A-Z
第四位:a-z
*/
var str = 'wAeA24DsaD34',
reg = /[^0][0-9A-z][A-Z][a-z]/g;
console.log(str.match(reg)); // ["24Ds"]
/*
(x | y) x或者y中的一个字符 加小括号优先级较高
*/
var str = '123zAeA24Dsa234w',
reg = /(123|234)[xyz]/g;
console.log(str.match(reg)); // ["123z"]
/*
匹配单词的边界:\b
*/
var str = 'Thiese is a Thise text',
reg = /\bThi\B/g;
console.log(str.match(reg)); // ["Thi", "Thi"]
第 2 章:正则表达式由两部分组成
2.1 元字符
2.1.1 量词元字符:设置出现的次数
元字符 | 含义 |
---|---|
* | 零到多次 |
+ | 一到多次 |
? | 零次或者一次 |
{n} | 出现n次 |
{n,} | 出现n到多次 |
{n,m} | 出现n到m次 |
举例说明:
/*
正则匹配的原则:
匹配成功不回头、
贪婪模式:能匹配多就不会匹配少,例如:abcdefg匹配成功,就不会再匹配 a、abc等
*/
var reg = /\w+/g;
str = 'abcdefg';
console.log(str.match(reg)); // ["abcdefg"]
/*
正则匹配的原则:
字符串从左到右,依次先匹配多,再匹配少,如果一旦匹配上就不回头匹配 =》 匹配成功不回头
贪婪匹配原则:能匹配多就不会匹配少
正则要求:* 0到多次
匹配过程:先匹配多,找到 abcdefg 当光标移动到g后面 再匹配空 ["abcdefg", ""]
【因为 abcdefg 匹配成功,所有不会回头匹配前面字母前后的空】,只能匹配g字母后面的空
*/
var reg = /\w*/g;
str = 'abcdefg';
console.log(str.match(reg)); // ["abcdefg", ""]
/*
正则匹配的原则:
匹配成功不回头、
贪婪模式:能匹配多就不会匹配少
正则要求:* 0到多次
匹配过程:先匹配 0-9之间的数字,找不到 然后在匹配空
光标走到哪里就匹配一个空 => 三个空 => a字母前后的空 和 b字母后的空
*/
var reg = /\d*/g;
str = 'ab';
console.log(str.match(reg)); // ["", "", ""]
/*
正则匹配的原则:
匹配成功不回头、
贪婪模式:能匹配多就不会匹配少
正则要求:* 0到多次
匹配过程:先匹配 0-9之间的数字,找不到 然后在匹配空
匹配三个空 =>a字母前后的空和b字母后的空
*/
var reg = /\w?/g;
str = 'ab';
console.log(str.match(reg)); // ["a", "b", ""]
/*
正则匹配的原则:
匹配成功不回头、
贪婪模式:能匹配多就不会匹配少
正则要求:
{n,m} 出现n到m次
{1,} 出现1到多次 === +
{0,} 出现0到多次 === *
{0,1} 出现0或者1次 === ?
*/
var reg = /\w{1, 2}/g;
str = 'abcdefg';
console.log(str.match(reg)); // ["ab", "cd", "ef", "g"]
/*
^n 匹配任何以n开头的字符串
*/
var reg = /^ab/g,
str = 'abcdabcd';
console.log(str.match(reg)); ["ab"]
2.1.2 特殊元字符:
单个或者组合在一起代表特殊的含义
元字符 | 含义 |
---|---|
\ | 转义字符(普通->特殊->普通) |
. | 可以匹配除了回车和换行的所有字符 |
^ 和 $ | ^ 以哪一个元字符作为开始,$ 以哪一个元字符作为结束 |
\d | === [0-9] 0~9之间的一个数字 |
\D | === [^\d] 非0~9之间的一个数字 【大写和小写的意思是相反的】 |
\w | === [0-9A-z_] 数字、字母、下划线中的任意一个字符 |
\W | === [^\w] 非数字、字母、下划线中的任意一个字符 |
\s | === [\r\n\t] 一个空白字符,包含:回车\r、空格、换行\n、制表符\t、\v垂直换行符、\f换页符 等 |
\S | === [^\s] |
\n、\t、 | 换行符\n、一个制表符\t(一个Tab键:四个空格) |
\b、\B | 匹配一个单词的边界\b;非单词边界\B |
x|y | x或者y中的一个字符 |
[xyz] | x或者y或者z中的一个字符 |
[^xy] | 除了x/y以外的任意字符 |
[a-z] | 指定a-z这个范围中的任意字符 [0-9a-zA-Z] === \W; |
[^a-z] | 上一个的取反“非” |
//=> 2.特殊元字符:单个或者组合在一起代表特殊的含义
****************************************************
() 正则中的分组符合
(?:) 只匹配不捕获
(?=) 只匹配不捕获、正向预查(设置一个正向条件,必须条件符合啥)
(?!) 只匹配不捕获、负向预查(设置一个负向条件,必须条件不符合啥)
普通元字符:
代表本身含义的
//=> 3.普通元字符:代表本身含义的
/zhangfeng/ 此正则匹配的就是 "zhufeng"
2.1.3 元字符详细解析
^ $
//=> ^/$ 两个都不加:字符串中包含符合规则的内容即可
let reg1 = /\d+/;
//=> ^/$ 两个都加:字符串只能是和规则一致的内容
let reg1 = /^\d+$/;
//=> 举个例子:验证手机号码(11位,第一个数字是1即可)
let reg = /^1\d{10}$/;
\
//=> .不是小数点,是除\n外的任意字符
let reg = /^2.3$/;
console.log(reg.test('2.3'));//=>true
console.log(reg.test('2@3'));//=>true
console.log(reg.test('23'));//=>false (因为2和3之间没有字符,结果为:false)
//=> 基于转义字符,让其只能代表小数点
let reg = /^2\.3$/;
console.log(reg.test('2.3'));//=>true
console.log(reg.test('2@3'));//=>false
//=> 在字符串中,\d也有特殊含义(0~9之间的任意数字),如果表示本身含义需要转义,如:\\d
let str = '\\d';
reg = /^\d$/;
console.log(reg.test(str));//=>false
reg = /^\\d$/;
console.log(reg.test(str));//=>true
x|y
let reg = /^18|29$/;
//=> 下面的打印结果,全是true
console.log(reg.test("18"))
console.log(reg.test("29"))
console.log(reg.test("129"))
console.log(reg.test("189"))
console.log(reg.test("1829"))
console.log(reg.test("829"))
console.log(reg.test("182"))
//=> -----直接x|y会存在很乱的优先级问题,一般我们写的时候都伴随着小括号进行分组,
//=> 因为小括号改变处理的优先级 => 小括号:分组
let reg = /^(18|29)$/;
console.log(reg.test("18"));//=> true
console.log(reg.test("29"));//=> true
console.log(reg.test("129"));//=> false
console.log(reg.test("189"));//=> false
console.log(reg.test("1829"));//=> false
console.log(reg.test("829"));//=> false
console.log(reg.test("182"));//=> false
//=> 只能是18或者29中的一个了
[]
//=> 1.中括号中出现的字符一般都代表本身的含义
//=> [@+] 表示:@或者+中的一个字符
let reg = /^[@+]+$/;
console.log(reg.test("@"));//=>true
console.log(reg.test("+"));//=>true
console.log(reg.test("@@"));//=>true
console.log(reg.test("@+"));//=>true
//=>例外情况:
//=>[\d] 中括号里面的\d 表示:0~9之间的任意数字
let reg = /^[\d]$/;
console.log(reg.test("d"));//=>false
console.log(reg.test("\\"));//=>false
console.log(reg.test("9"));//=>true
//=>中括号中不存在多位数
reg = /^[18]$/;
console.log(reg.test("1"));//=>true
console.log(reg.test("8"));//=>true
console.log(reg.test("18"));//=>false
//=>例如:
let reg = /^[10-29]$/; //=>1或者0-2或者9
console.log(reg.test("1"));//=>true
console.log(reg.test("9"));//=>true
console.log(reg.test("0"));//=>true
console.log(reg.test("2"));//=>true
console.log(reg.test("0-2"));//=>false
console.log(reg.test("10"));//=>false
let reg = /^[(10-29)]$/; //=>( 或者 1 或者 0-2 或者 9 或者 )
console.log(reg.test("("));//=>true
console.log(reg.test(")"));//=>true
2.2 修饰符
//=> 正则表达式常用的修饰符:img
i =>ignoreCase 忽略单词大小写匹配
m =>multiline 可以进行多行匹配
g =>global 全局匹配
第 3 章:正则的捕获
3.1 实现正则捕获的方法
方法 | 函数 |
---|---|
正则RegExp.prototype上的方法 | exec()、test() |
字符串String.prototype上支持正则表达式 处理的方法 | replace()、match()、splite() |
- test也能捕获 (本意是匹配)
let str = "{0}年{1}月{2}日";
let reg = /\{(\d+)\}/g;
console.log(reg.test(str));//=>true
console.log(RegExp.$1);//=> 0
console.log(reg.test(str));//=>true
console.log(RegExp.$1);//=> 1
console.log(reg.test(str));//=>true
console.log(RegExp.$1);//=> 2
console.log(reg.test(str));//=>false
console.log(RegExp.$1);//=> 2 存储的是上一次捕获的结果
//=>RegExp.$1 ~ RegExp.$9:获取当前本次正则匹配后,第一个到第九个分组的信息
- replace字符串中实现替换的方法(一般都是伴随正则一起使用的)
- 把“zhufeng”替换成“珠峰”
//=>1.不用正则,执行一次只能替换一个
let str = "zhufeng@2019|zhufeng@2020"
str = str.replace("zhufeng","珠峰").replace("zhufeng","珠峰")
console.log(str);//=>珠峰@2019|珠峰@2020
//=>2.使用正则会简单一点
let str = "zhufeng@2019|zhufeng@2020"
str = str.replace(/zhufeng/g,"珠峰");
console.log(str);//=>珠峰@2019|珠峰@2020
- 把"zhufeng"替换为"zhufengpeixun"
//=>基于正则g可以实现
let str = "zhufeng@2019|zhufeng@2020"
str = str.replace(/zhufeng/g,"zhufengpeixun");
console.log(str);//=>zhufengpeixun@2019|zhufengpeixun@2020
案例:把时间字符串进行处理
//=>方法1: let time = "2019-08-13"; let reg = /^(\d{4})-(\d{1,2})-(\d{1,2})$/g; time = time.replace(reg,"$1年$2月$3日"); console.log(time)//=>2019年08月13日 //=>方法2:[str].replace([reg],[function]) // 1.首先拿reg 和 time 进行匹配捕获,能匹配到几次就会把传递的函数执行几次 // (而且是匹配一次就执行一次) // 2.不仅把方法执行,而且replace还给方法传递了实参信息 // (和exec捕获的内容一致的信息:大正则匹配的内容,小分组匹配的信息...) // 3.在函数中我们返回的是啥,就把当前大正则匹配的内容替换成啥 let time = "2019-08-13"; let reg = /^(\d{4})-(\d{1,2})-(\d{1,2})$/g; time = time.replace(reg,(big,$1,$2,$3)=>{ //=>这里的$1 ~ $3 是我们自己设置的变量 console.log(big,$1,$2,$3) }) //=> 一般我们这样书写: let time = "2019-08-13"; let reg = /^(\d{4})-(\d{1,2})-(\d{1,2})$/g; time = time.replace(reg, (...arg) => { let [, $1, $2, $3] = arg $2.length < 2 ? $2 = "0" + $2 : null; $3.length < 2 ? $3 = "0" + $3 : null; return $1 + "年" + $2 + "月" + $3 + "日" }) console.log(time); //=>2019年08月13日
案例:单词首字符大写
let str = "good good study, day day up!"; let reg = /\b([a-zA-Z])[a-zA-Z]*\b/g; //=> 函数被执行了六次,每一次都把正则匹配信息传递给函数 //=> 每一次arg: ["good","g"] ["good","g"] ["study","s"] ... str = str.replace(reg,(...arg)=>{ let [content,$1] = arg; // 首字符大写 $1 = $1.toUpperCase(); // 出第一个字母以外,其余都拿到 例如:good 除了g不要,剩余的 ood 都要拿到 content = content.substring(1); return $1 + content // G 拼接 ood 得到 Good }) console.log(str); //=>Good Good Study, Day Day Up!
let str = "zhufnengjjdaf2001jkjk2004";
let reg = /^\d+s/;
//=>实现正则捕获的前提是:当前正则要和字符串匹配,如果不匹配捕获的结果是null
console.log(reg.test(str)); //=>false
console.log(reg.exec(str)); //=>null
3.2 正则捕获的贪婪性
//=>正则捕获的贪婪性:默认情况下,正则捕获的时候,是按照当前正则所匹配的最长结果来获取的
let str = "接口2019@2020培新"
let reg = /\d+/g;
console.log(str.match(reg));//=>["2019", "2020"]
//=>在量词元字符后面设置? 取消捕获时候的贪婪性(按照正则匹配的最短结果来获取)
let str = "接口2019@2020培新"
reg = /\d+?/g;
console.log(str.match(reg));//=>["2", "0", "1", "9", "2", "0", "2", "0"]
问号在正则中的5大作用
- 问号左边是非量词元字符:本身代表量词元字符,出现零到一次
- 问号左边是量词元字符:取消捕获时候的贪婪性
- (?😃 只匹配不捕获
- (?=) 正向预查
- (?!) 负向预查
3.3 正则捕获的懒惰性
/*
基于exec实现正则的捕获:
1.捕获到的结果是null 或者 一个数组
第一项:本次捕获的内容
其余项:对应小分组本次单独捕获的内容
index:当前捕获内容在字符串中的起始索引
input:原始字符串
2.每执行一次exec,只能捕获到一个符合正则规则的,但是默认情况下,我们执行多次(无数次),获取的结果永远都是第一个匹配到的内容,其余的捕获不到。 //=>"正则捕获的懒惰性":默认只捕获第一个
*/
let str = "zhufnengjjdaf2001jkjk2004";
let reg = /\d+/;
console.log(reg.exec(str));
//=>结果:["2001", index: 13, input: "zhufnengjjdaf2001jkjk2004", groups: undefined]
- 正则捕获的懒惰性的原因:
let str = "zhufnengjjdaf2001jkjk2004";
let reg = /\d+/;
console.log(reg.lastIndex);//=>0 下面匹配捕获是从STR索引零的位置开始找
console.log(reg.exec(str));
console.log(reg.lastIndex);//=>0 第一次匹配捕获完成,lastIndex没有改变,所以下一次exec依然是从字符串最开始找,找到的永远是第一个匹配到的
/*
reg.lastIndex : 当前正则下一次匹配的起始索引位置
懒惰性捕获的原因:默认情况下lastIndex的值不会被修改,每一次都是从字符串开始位置查找,
所以找到的永远只是第一个
*/
- 懒惰性捕获的解决方法: 全局匹配修饰符g
//=> 设置全局匹配修饰符g后,第一次匹配完;lastIndex会自己修改
let str = "zhufnen2019gjjdaf2001jkjk2004";
let reg = /\d+/g;
console.log(reg.exec(str)); //=>["2019"...]
console.log(reg.lastIndex); //=>11
console.log(reg.exec(str)); //=>["2001"...]
console.log(reg.lastIndex); //=>21
console.log(reg.exec(str)); //=>["2004"...]
console.log(reg.lastIndex); //=>29
console.log(reg.exec(str)); //=>null 当全部捕获后,再次捕获的结果是null,但是lastIndex又回归了初始值零,再次捕获又从第一个开始了...
console.log(reg.lastIndex); //=>0
console.log(reg.exec(str)); //=>["2019"...]
console.log(reg.lastIndex); //=>11
//=>...依次循环
- 验证一下:只有正则和字符串匹配,我们再捕获 ( 不能采用下面的方法 )
let str = "zhufnen2019gjjdaf2001jkjk2004";
let reg = /\d+/g;
if(reg.test(str)) {
console.log(reg.lastIndex); //=>11 基于TEST匹配验证后,lastIndex已经被修改为第一次匹配后的结果,所以下一次捕获不再从头开始了
console.log(reg.exec(str)); //=>["2001"...]
}
- 字符串中的match方法原理:
~function () {
function execAll(str = "") {
//=>str: 要匹配的字符串
//=>this: RegExp的实例(当前操作的正则)
//=>进来后的第一件事,是验证当前正则是否设置了g,不设置则不能再进行循环捕获了,否则会导致死循环
if (!this.global) return this.exec(str);
//=>ary 存储最后所有捕获的信息 res 存储每一次捕获的内容
let ary = []
res = this.exec(str)
while (res) {
//=>把每一次捕获的内容res[0]存放到数组中
ary.push(res[0]);
//=>只要捕获的内容不为null,则继续捕获下去
res = this.exec(str)
}
return ary
}
RegExp.prototype.execAll = execAll
}();
let str = "zhufnen2019gjjdaf2001jkjk2004";
let reg = /\d+/g;
console.log(reg.execAll(str)) //=> ["2019", "2001", "2004"]
//=>字符串中的match方法,可以在执行一次的情况下,捕获到所有匹配的数据(前提是:正则也得设置g才可以)
console.log(str.match(reg)); //=> ["2019", "2001", "2004"]
- match方法的局限性:
//=>多次匹配的情况下,match只能把大正则匹配的内容获取到,小分组匹配的信息无法获取
let str = "{0}年{1}月{2}日";
let reg = /\{(\d+)\}/g;
console.log(str.match(reg));
//=>结果:["{0}", "{1}", "{2}"]
3.4 正则的分组捕获
1.//=>身份证号码
let reg = /^(\d{6})(\d{4})(\d{2})(\d{2})\d{2}(\d)(\d|x)$/g
let str = "130828199012040112"
console.log(reg.exec(str));
//=>结果:["1 30828199012040112", "130828", "1990", "12", "04", "1", "2", index: 0, input: "130828199012040112", groups: undefined]
//=>第一项:大正则匹配的结果
//=>其余项:每一个小分组单独匹配捕获的结果
//=>如果设置了分组(改变优先级),但是捕获的时候不需要单独捕获,可以基于?:来处理
console.log(str.match(reg));
//=>结果:["130828199012040112"]
//=>既要捕获到数字{数字},也想单独的把数字也获取到,
//=>例如:第一次找到{0};还需要单独获取 0
let str = "{0}年{1}月{2}日";
//=>不设置g只匹配一次,exec和match获取的结果一致(既有大正则匹配的信息,也有小分组匹配的信息)
let str = "{0}年{1}月{2}日";
let reg = /\{(\d+)\}/;
console.log(reg.exec(str));
console.log(str.match(reg));
//=>结果:["{0}", "0", index: 0, input: "{0}年{1}月{2}日", groups: undefined]
//=>多次匹配的情况下,match只能把大正则匹配的内容获取到,小分组匹配的信息无法获取
let str = "{0}年{1}月{2}日";
let reg = /\{(\d+)\}/g;
console.log(str.match(reg));
//=>结果:["{0}", "{1}", "{2}"]
//=>解决方法:
let str = "{0}年{1}月{2}日";
let reg = /\{(\d+)\}/g;
let aryBig = []
arySmall = []
res = reg.exec(str)
while (res) {
let [big, small] = res;
aryBig.push(big);
arySmall.push(small);
res = reg.exec(str)
}
console.log(aryBig,arySmall)
//=>结果:["{0}", "{1}", "{2}"] ["0", "1", "2"]
3.5 正则的分组引用
//=>分组的第三个作用: “分组引用”
let str = "book"
//=> 分组引用就是通过“\数字”让其代表和对应分组出现一模一样的内容
let reg = /^[a-zA-Z]([a-zA-Z])\1[a-zA-Z]$/
console.log(reg.test(str)) //=>true