• 【小贴士】探一探javascript中的replace


    javascript字符串与数组有很多精巧的方法,比如splice、indexOf,而replace在字符串处理中偶尔会产生让人愉悦的效果

    比如underscore中的模板引擎替换部分,又如信用卡分割的应用

    简单来说,replace用于将字符串中一些字符替换为另一些字符,最简单的情况如下

    var num = '1234567890123456';
    var numStr = '';
    numStr = num.replace('1', 'a');
    console.log(numStr);//a234567890123456

    这个结果,事实上不太理想,因为他只替换了一个,后面的1没有理我,于是这个时候正则便出现了

    var num = '1234567890123456';
    var numStr = '';
    numStr = num.replace(/1/g, 'a');
    console.log(numStr); //a234567890a23456

    一个经典例子是,javascript实现的trim方法

    String.prototype.trim = function () {
      return this.toString().replace(/(^s*)|(s*$)/g, '');
    };
    var str = ' sssssds  ';
    alert('|' + str.trim() + '|'); //|sssssds|

    正则出现的时候便会有一些比较特殊的标识“$”

    字符替换文本
    $1、$2、...、$99 与 regexp 中的第 1 到第 99 个子表达式相匹配的文本。
    $& 与 regexp 相匹配的子串。
    $` 位于匹配子串左侧的文本。
    $' 位于匹配子串右侧的文本。
    $$ 直接量符号。
    var str = ' 123 ';
    console.log(str.replace(/(^s*)|(s*$)/g, '-$&-')); //- -123- ---

    一切都很美好的时候,不满足的情况发生了,我们感觉这个结果与预期不符,具体原因我们后面再说,这里先看看函数回调情况

    var str = ' 123 ';
    var arr = [];
    /*
    参数一为匹配到的字符串
    参数二为子表达式中的数据对应( $i (i:1-99)),带|号便会产生(注意这里可能产生多个参数匹配)
    参数三为匹配字符串的匹配下标
    最后一个参数表示字符串本身
    */
    console.log(str.replace(/(^s*)|(s*$)/g, function (match, $1, $2, offset) {
      console.log(arguments);
      arr.push('-' + (match || '') + '-');
      return '-' + (match || '') + '-';
    }));
    console.log(arr); //- -123- ---

    以上其实想简单说明下函数与$的关系,导致输出的原因是因为正则没有写对:

    var str = ' 123 ';
    console.log(str.replace(/^(s+)|(s+)$/g, '-$&-')); 

    PS:上面那个正则还是抄的,所以以后碰到类似问题还是得自己验证才行啊

    另外,我有一个信用卡账号要做格式转换:123456789012 => 1234 5678 9012

    这个代码要用replace的话,不用函数便行不通的

    一旦匹配成功,会替换为后面函数的的返回值,这个函数匹配成功几次便会调用几次,有些时候我们可以把它当做一个循环使用

    var num = '123456789012';
    var reg = /d{4}/g;
    var index = 0;
    var arr = [];
    
    num.replace(reg, function (match, offset) {
      arr.push(match);
    });
    console.log(arr.join(' ')); //1234 5678 9012 

    最后我们来看看我们的underscore模板引擎语法,现在我们有一个模板字符串,我们要将它转换为一个函数,于是我们会这么做

     1 var template = [
     2 '<ul class="ul-list" style="position: absolute;  100%; top: 0; left: 0;">',
     3   '<%for(var i = 0, len = data.length; i < len; i++) { %>',
     4   '<li data-key="<%=data[i].id %>" data-index="<%=i%>" <%if(data[i].disabled){ %> class="disabled"',
     5     '<%} %>>',
     6     '<%=data[i].name %></li>',
     7   '<%} %>',
     8 '</ul>',
     9 '<div class="cui-mask-gray">',
    10 '</div>',
    11 '<div class="cui-lines">',
    12   '&nbsp;</div>'
    13 ].join('');
    14 
    15 var escapes = {
    16   "'": "'",
    17   '\': '\',
    18   '
    ': 'r',
    19   '
    ': 'n',
    20   '	': 't',
    21   'u2028': 'u2028',
    22   'u2029': 'u2029'
    23 };
    24 var escaper = /\|'|
    |
    |	|u2028|u2029/g;
    25 
    26 var index = 0;
    27 var source = "__p+='";
    28 var matcher = /(<%-[sS]+?)%>|<%=([sS]+?)%>|<%([sS]+?)%>|$/g;
    29 
    30 template.replace(matcher, function (match, escape, interpolate, evaluate, offset) {
    31   source += template.slice(index, offset)
    32         .replace(escaper, function (match) { return '\' + escapes[match]; });
    33 
    34   if (escape) {
    35     source += "'+
    ((__t=(" + escape + "))==null?'':_.escape(__t))+
    '";
    36   }
    37   if (interpolate) {
    38     source += "'+
    ((__t=(" + interpolate + "))==null?'':__t)+
    '";
    39   }
    40   if (evaluate) {
    41     source += "';
    " + evaluate + "
    __p+='";
    42   }
    43   index = offset + match.length;
    44   return match;
    45 });
    46 source += "';
    ";
    47 
    48 source = 'with(obj||{}){
    ' + source + '}
    ';
    49 
    50 source = "var __t,__p='',__j=Array.prototype.join," +
    51       "print=function(){__p+=__j.call(arguments,'');};
    " +
    52       source + "return __p;
    ";
    53 
    54 console.log(source);

    上面的代码打印出的东西:

    var __t,__p='',__j=Array.prototype.join,print=function(){__p+=__j.call(arguments,'');};
    with(obj||{}){
    __p+='<ul class="ul-list" style="position: absolute;  100%; top: 0; left: 0;">';
    for(var i = 0, len = data.length; i < len; i++) { 
    __p+='<li data-key="'+
    ((__t=(data[i].id ))==null?'':__t)+
    '" data-index="'+
    ((__t=(i))==null?'':__t)+
    '" ';
    if(data[i].disabled){ 
    __p+=' class="disabled"';
    } 
    __p+='>'+
    ((__t=(data[i].name ))==null?'':__t)+
    '</li>';
    } 
    __p+='</ul><div class="cui-mask-gray"></div><div class="cui-lines">&nbsp;</div>';
    }
    return __p;

    代码复杂度稍有提升,但是原理与上面一样,各位自己读下吧,今天的学习到此

  • 相关阅读:
    centos7-关闭 rpcbind 服务
    nginx进行获取阿里云slb真实ip配置操作
    rsync同步时,删除目标目录比源目录多余文件的方法(--delete)
    nfs安装
    Selenium+PhantomJS使用时报错原因及解决方案
    python json转对象 指定字段名称
    大地坐标系和空间直角坐标系的转换
    python日志输出的内容修改为json格式
    Java String的intern方法
    python 超时重试的方法 signal手段
  • 原文地址:https://www.cnblogs.com/yexiaochai/p/3942194.html
Copyright © 2020-2023  润新知