大家好,对于正则表达式只是简单的知道一些语法,今天碰到一个优点难的问题,花了好长时间还是写不出来,只能来这里求教了,希望大家能帮我一下。需求是这样的,我在一堆字符串中 要在这堆中找出字符串中 同时包含了 "string1"和"string2" 的字符串,而且这堆字符串中可能有换行之类的。example:
1:
123123123 ...string1 ....23123123
.....
2323 string2...12315552: 23123string2......
123123123string112345553: string112312409
sdfasdfsdfsdf4: sdfsdfasdfsdfsstring2....如何用一个正则表达式,让结果返回1和2?

解决方案 »

  1.   

    var re = /string1.*string2|string2.*string1/i
    if (re.test(str)) ...
      

  2.   


    哦对\nvar re = /string1[\s\S]*string2|string2[\s\S]*string1/i
      

  3.   

    还新人,这么变态的要求。。没想出来。。暂时的解决办法。。<script>var s='1:\n'
    +'123123123 ...string1 ....23123123\n'
    +'....\n.'
    +'2323 string2...1231555\n'+'2: 23123string2......\n'
    +'123123123string11234555\n'+'3: string112312409\n'
    +'sdfasdfsdfsdf\n'+'4: sdfsdfasdfsdfsstring2....'
    var rx=/\d+:/g,split=s.match(rx),rst=[],arr=s.split(rx);
    for(var i=1;i<arr.length;i++)
     if(arr[i].indexOf('string1')!=-1&&arr[i].indexOf('string2')!=-1)rst[rst.length]=split[i-1].replace(':','');alert(rst)
    </script>
      

  4.   

    结果是对了,但是我想要一个正则……我想了想 也看了下4楼朋友的,得出下面这样一个正则:
    (string1+(.*\n*.*)*string2+)|(string2+(.*\n*.*)*string1+)但是在我一个测试程序里面运行,死后不对啊,是不是我语法错了,还是不同编程语言直接的换行符不对?还是正则太复杂了?
      

  5.   

    看了4楼的回复,我凌乱了,你的example 1,2,3,4 是1个字符串还是4个字符串,4个字符串3楼的正则测试再处理是没问题的,1个字符串正则:var s='1:\n'
    +'123123123 ...string1 ....23123123\n'
    +'....\n.'
    +'2323 string2...1231555\n'+'2: 23123string2......\n'
    +'123123123string11234555\n'+'3: string112312409\n'
    +'sdfasdfsdfsdf\n'+'4: sdfsdfasdfsdfsstring2....'var re = /^\d+(?=:[^:]*(?:string1[^:]*string2|string2[^:]*string1))/gimalert(s.match(re)) //1, 2
      

  6.   

    写得真是超优雅。[PS:不嫌麻烦的话解释一下吧,我用(\w+)去拼接,死活不对]4楼 showbo 写的好像在处理的时候有点小问题需要修正一下var a=/\w+:/g,b=s.match(a),c=s.split(a),d=[];
    for(var i=0;i<b.length;i++){
        if(c[i].indexOf('string1')!=-1 && c[i].indexOf('string2')!=-1){
            d.push(b[i].replace(':',''));
        }
    };
    alert(d);
      

  7.   

    就这个需求来说,完全用正则来解的话并不合适
    'use strict';var s = (
      '1:\n' 
     +'123123123 ...string1 ....23123123\n' 
     +'....\n.' 
     +'2323 string2...1231555\n' 
     
     +'2: 23123string2......\n' 
     +'123123123string11234555\n' 
     
     +'3: string112312409\n' 
     +'sdfasdfsdfsdf\n' 
     
     +'4: sdfsdfasdfsdfsstring2....'
    );var m, cfgName, cfgVal, kws, a = [];
    var cfgPatten = /(\d+):([\S\s]+?)(?=(\d+:|$))/g;
    var kwPatten  = /string\d/g;
    var mastInc   = ['string1', 'string2'];var contains = function(a, items){
      var inArray = (
          Array.prototype.indexOf 
        ? function(a, v){ 
          return a.indexOf(v) != -1; 
        } 
        
        : function(a, v){
          var i, len = a.length;
          for(i=0; i<len; i++){
            if(a[i] == v){
              return true;
            }
          }
          return false;
        }
      );  var i, c, len = items.length;
      for(i=0, c=0; i<len; i++){
        if( inArray(a, items[i]) ){
          c++;
        }    
      }
      
      return c == len;
    }
    while( m = cfgPatten.exec(s) ){
      cfgName = m[1];
      cfgVal  = m[2];   
      kws = cfgVal.match(kwPatten);  if( contains(kws, mastInc) ){
        a.push(cfgName);    
      }
    }console.log(a);
      

  8.   


    搞得那么复杂,还真不如完全用正则,优雅有余性能稍欠。8楼正则的缺点是回溯太多,正则的效率取决于对文本的了解,楼主给的文本太抽象导致正则也只能抽象,回溯免不了。不过确实[^:]*贪婪改为[^:]*?非贪婪会好点,因为string1/2的问题可能要扫两次,所以还是比你的cfgPatten慢,但是用正则扫完结果就出来了,而你还要调用一堆对象处理,所以断言性能稍欠(我未测试过)。综合性能最好应该是4楼 showbo 的,split、indexOf测试,不涉及回溯。
      

  9.   

    那个正则还有优化的余地,当时写的比较仓促其实玩去可以用match来代替exec的。
    但如果你完全用正则的话,根本无法将问题扩展到多个关键字的情况,你写个同时
    包含5个关键字的正则试试。但如果把问题拆分的话可以很方便的处理任意关键字。
      

  10.   

    4楼的做法比较高效, 但indexOf有些情况下会产生误判。
    其实真实环境中可能的需求是这样的:查找同时包含两
    个关键字的配置项。这时候indexOf很容易产生误判。如果关键字换一下换成
    string1 string2 那么包含string12 string21的就会被匹配。
    当然了如果只是模糊匹配的话这倒无所谓。
      

  11.   


    var s = [
     '2: 23123string2......\n' 
     +'123123123string11234555\n' ,
      '1:\n' 
     +'123123123 ...string1 ....23123123\n' 
     +'....\n.' 
     +'2323 string2...1231555\n' ,  '3: string112312409\n' 
     +'sdfasdfsdfsdf\n' ,
     
     '4: sdfsdfasdfsdfsstring2....',
    ];

    var reg = /^(?=[\S\s]*string1)(?=[\S\s]*string2)/;
    for (var i = 0, length = s.length; i < length; i++) {
    console.log(reg.test(s[i]));
    }
      

  12.   

    楼上的处理是有问题的,先出现string2然后出现string1也是符合要求的