var a = 'aabbccdd';
alert(a.replace(/(a.*)(?=c)/gi,'-')); //  -cdd
alert(a.replace(/(a.*)?(?=c)/gi,'-')); //  --cdd
alert(a.replace(/(a.*?)(?=c)/gi,'-')); //  -ccdd
alert(a.replace(/(a.*?)?(?=c)/gi,'-')); //  --c-cdd
求解释以上结果为什么是这样。

解决方案 »

  1.   

    第一个,应该是贪婪模式匹配 a.*,并在最后一个 c 字符前才停止,我大概是这么理解
    第二个,我理解不能
    第三个,应该是非贪婪模式匹配 a.*,并在第一个 c 字符前停止,应该是
    第四个,彻底思维停止。
      

  2.   

    第二个非贪婪  aabbccdd    aabbc》替换aabb 变成  ccdd   继续替换 cc》替换成c  结果 --cdd
      

  3.   

    第四种也是非贪婪模式:alert(a.replace(/(a.*?)?(?=c)/gi,'-')); // aabbccdd  --c-cddaabbccdd》a-ccdd
    a-ccdd》》-ccdd
    -ccdd》--ccdd
    --ccdd》--c-cdd结果  --c-cdd
      

  4.   

    第四种也是非贪婪模式:alert(a.replace(/(a.*?)?(?=c)/gi,'-')); // aabbccdd --c-cddaabbccdd》a-ccdd
    a-ccdd》》-ccdd
    -ccdd》--ccdd
    --ccdd》--c-cdd结果 --c-cdd
      

  5.   

    @@,看不明白,他匹配的到底是什么地方?(a.*)?(?=c)  aabbccdd => -cdd ,这样才对吧?即便是非贪婪模式,也应该是 aabbccdd => -ccdd,怎么还会继续匹配替换呢?已经没有符合 a.*这个分组的匹配项了啊
      

  6.   

    (a.*)?  什么都没有也可以  什么都没有 后面跟个c 就是在c前面插入1个-
      

  7.   

    刚加了个 ^ 测试,还是不明白
    alert(a.replace(/(^a.*)?(?=c)/gi,'-')); //  --cdd
    alert(a.replace(/^(a.*)?(?=c)/gi,'-')); //  -cdd
    下边这个可以确认匹配了一次 ^aabbccdd => -cdd
    上边那个还是不能理解。
      

  8.   

    ^ 表示从开始处开始匹配(^a.*)?  括号内  是a开始  这个和 (a.*)?(?=c) 无差别 因为 括号内存在的唯一方式就是a开头
      

  9.   

    还是不太理解啊,我可以理解为,匹配到的位置,参与运算,但匹配的内容和我想的不太一样啊alert(a.replace(/(a.)?(?=c)/gi,'-') + '\n' + (/(a.)?(?=c)/gi).exec(a));
    // aabb-c-cdd
    // ,
    // 这个是匹配到两次(?=c),前边的(a.)是无效的?alert(a.replace(/(a.)(?=c)/gi,'-') + '\n' + (/(a.)(?=c)/gi).exec(a));
    // aabbccdd
    // null
    // 那么,这个 a. 为什么就有效了?alert(a.replace(/(a.*)(?=c)/gi,'-') + '\n' + (/(a.*)(?=c)/gi).exec(a));
    // -cdd
    // aabbc,aabbcalert(a.replace(/(a.*)?(?=c)/gi,'-') + '\n' + (/(a.*)?(?=c)/gi).exec(a));
    // --cdd
    // aabbc,aabbc
    // 现有不管中间有没有问号,exec得到的内容是一样的,为什么replace会不一样?alert(a.replace(/(a.*?)(?=c)/gi,'-') + '\n' + (/(a.*?)(?=c)/gi).exec(a));
    // -ccdd
    // aabb,aabbalert(a.replace(/(a.*?)?(?=c)/gi,'-') + '\n' + (/(a.*?)?(?=c)/gi).exec(a));
    // --c-cdd
    // aabb,aabb
      

  10.   

    第一个:你的理解差不多吧。。
    第二个:符号“?”有2个语义,当该字符紧跟在任何一个其他限制符 (*, +, ?, {n}, {n,}, {n,m}) 后面时,匹配模式是非贪婪的,而用在其他地方,比如do(es)?其作用和{0,1}等价,可以匹配do和does,所以这个正则也不难理解了,该正则等价于/(a.*)(?=c)|(?=c)/gi,会匹配aabbc以及一个空匹配
    第三个:你理解得也差不多吧。。
    第四个:和第二个差不多,关键在于?是有2个语义的。。
      

  11.   

    给你段代码,方便你理解(在chrome或装有firebug的firebox上运行) var a = 'aabbccdd';
    console.log(a.replace(/(a.*)(?=c)/gi,'-')); //  -cdd
    console.log(a.replace(/(a.*)?(?=c)/gi,'-')); //  --cdd
    console.log(a.replace(/(a.*?)(?=c)/gi,'-')); //  -ccdd
    console.log(a.replace(/(a.*?)?(?=c)/gi,'-')); //  --c-cdd

    console.group("/(a.*)(?=c)/gi");
    a.replace(/(a.*)(?=c)/gi, function(){
    console.dir(arguments);
    })
    console.groupEnd();
    console.group("/(a.*)?(?=c)/gi");
    a.replace(/(a.*)?(?=c)/gi, function(){
    console.dir(arguments);
    })
    console.groupEnd();
    console.group("/(a.*?)(?=c)/gi");
    a.replace(/(a.*?)(?=c)/gi, function(){
    console.dir(arguments);
    })
    console.groupEnd();
    console.group("/(a.*?)?(?=c)/gi");
    a.replace(/(a.*?)?(?=c)/gi, function(){
    console.dir(arguments);
    })
    console.groupEnd();
      

  12.   

    亲,replace和exec差别很大的。。详情自己google,网上很多