模糊点:对于这个两个正则表达式不理解,读不懂

let evalExpr = /<%=(.+?)%>/g;
let expr = /<%([\s\S]+?)%>/g;

首先是不明白正则表达式中 '?' 符号的含义,也就是懒惰匹配,其次是 [/s/S] 的意思不理解。另外在解决问题中发现自己对于正则表达式 ^ $ 理解不透彻,还有一个就是对于字符串方法replace的用法理解太模糊。




问题一:懒惰匹配

上面实例代码中使用懒惰匹配的目的是,要找出字符串中包含的所有的以<%开头,以%>结尾的子字符串,如果不是懒惰匹配那代码会只返回一个字符串,举例:

let evlExpr = /<%(.*)%>/g;
let evlExpr1 = /<%(.*?)%>/g;
let str = '<% for(let i=0; i < data.supplies.length; i++) { %><li><%= data.supplies[i] %></li><% } %>';
str.replace(evlExpr,function(match){
  console.log(match);
});
str.replace(evlExpr1,function(match){
  console.log(match);
})

输出:

"<% for(let i=0; i < data.supplies.length; i++) { %><li><%= data.supplies[i] %></li><% } %>"
"<% for(let i=0; i < data.supplies.length; i++) { %>"
"<%= data.supplies[i] %>"
"<% } %>"


问题二:[/s/S]问题

'[/s/S]'与 '.'的区别:"."是不会匹配换行的,所有出现有换行匹配的时候,人们就习惯 使用[\s\S]或者[\w\W]这样的完全通配模式。




问题三:^ 和 $ 问题

模式中的 ^ 是要求被匹配的字符串必须以指定字符开头的,例如

let par = /^ad/; 

let s = 'apdgx'; 

let s1 = 'tadniix'; 

let s2 = 'adjxe'; 

console.log(par.exec(s));  //null 

console.log(par.exec(s1));  //null 

console.log(par.exec(s2));  //["ad"]





$与上面问题相似,以此类推




问题四:String.replace()

参数有两个 String.replace(regexp|substr, newSubStr|function)


regexp:以正则表达式作为第一个参数,正则表达式所匹配到的子字符串都将被第二个参数的返回值所替换。 


substr:一个要被newSubstr替换掉的字符串(函数返回值也可以替换)。其被视为一个整个字符串,而不是一个正则表达式,仅仅是第一个匹配会被替换。


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


function:一个用来创建新子字符串的函数,该函数的返回值将替换掉第一个参数匹配到的结果。




其中重点是了解,newSubStr 和 function :


1.newSubStr


变量名

代表的值


$$

        插入一个 "$"。


$&

        插入匹配的子串。


$`

        插入当前匹配的子串左边的内容。


$'

        插入当前匹配的子串右边的内容。


$n

        假如第一个参数是 RegExp对象,并且 n 是个小于100的非负整数,那么插入第 n 个括号匹配的字符串。


举例用法: 


let s1 = 'tadniix'; 

let s5 = s1.replace('nii','$`');  // "tadtadx"


2.function


你可以指定一个函数作为第二个参数。在这种情况下,当匹配执行后,该函数就会执行。函数的返回值作为替换字符串(注意:上面提到的特殊替换参数在这里不能被使用。)另外重点注意:如果第一个参数是正则表达式,并且其为全局匹配模式,那么这个方法将被多次调用,每次匹配都会调用。


变量名

代表的值


match

匹配的子串。(对应于上述的$&。)


p1,p2, ...

假如replace()方法的第一个参数是一个RegExp 对象,则代表第n个括号匹配的字符串。(对应于上述的$1,$2等。)


offset

匹配到的子字符串在原字符串中的偏移量。(比如,如果原字符串是“abcd”,匹配到的子字符串是“bc”,那么这个参数将是1)


string

被匹配的原字符串。




用法:上面的变量名都是作为function的参数去使用,例一


let s1 = 'tadniix'; 

s1.replace('dni',function(){ 

  console.log(arguments); 

});  

 // 输出(因为没有) 

[object Arguments] { 

  0: "dni", 

  1: 2, 

  2: "tadniix" 

}





例二:


let s1 = 'tadniix'; 

s1.replace(/(dni)/,function(){ 

  console.log(arguments); 

  return 'ss77'; 

}); 

//输出 

[object Arguments] { 

  0: "dni",  //匹配的自串 

  1: "dni",  //捕获组 

  2: 2,      //偏移量 

  3: "tadniix"   //元字符串 

}



以上可以看出arguments对应的就是上表中的四个变量