获取2个单词之间的字符串,其中也包含这些单词

时间:2015-08-13 13:27:23

标签: javascript regex

我有字符串,我想在其中找到2个字:'开始'和'结束'。

'开始'和'结束'总是聚集在一起(也许我会在他们之间有另一个角色,但如果我有'开始 ',我也会'结束'。

我尝试使用regEx源找到第一个'开始'而不是他自己的'结束',它会返回正确的子字符串。

字符串的例子: [我在这个例子索引中为每一对'开始'和'结束'写了只是为了清晰(在真正的字符串中我不会有这个索引) - 答案总是在index(1)]

之间
  1. 某事开始 something_needed 结束某事// print 'something_needed'
  2. 开始(1)某事开始(2)某事结束(2)某事结束(1)开始结束// print 'something start(2) something end(2) something'
  3. 开始(1)某事开始(2)开始(3)某事结束(3)事情开始(4)结束(4)事情结束(2)事情结束(1)某事开始(5)某事结束(5)// print 'something start**(2) start(3) something end(3) something start(4) end(4) something end(2) something'
  4. 这是我在Javascript中的解决方案,但我更喜欢仅在regEx中的答案。

    我发现所有开始,之后所有结束,并且 - 每次开始:count ++,每个结束:count--。当count == 0时,它是正确的结束的位置。

    function getStartEnd(str) {
        str = " "+str+" ";
        var start = matchPosArr(str, /[\d\s\r\n,\(\)\[\]\{\}]+START+(?=[\d\s\r\n,\(\)\[\]\{\}])/gi);
        var end = matchPosArr(str, /[\d\s\r\n,\(\)\[\]\{\}]+END+(?=[\d\s\r\n,\(\)\[\]\{\}])/gi);
        var count = 0;  // counter
        var si = 0;     // index of start array
        var ei = 0;     // index of end array
        var isStart = false;
        while (true) {
            if (ei >= end.length) {
                alert('error');
                break;
            }
            else if (si >= start.length) {
                ei++;
                count--;
                if (count == 0) {
                    ei--;
                }
            }
            else if (start[si] > end[ei]) {
                ei++;
                count--;
            }
            else if (start[si] < end[ei]) {
                si++;
                count++;
            }
            if (count == 0 && isStart==true) {
                break;
            }
            isStart = true;
        }
        return str.substring(start[0]+("start ".length),end[ei]);
    }
    function matchPosArr(str, regEx) {
        var pos = []; 
        while ((match = regEx.exec(str)) != null) {
            pos.push(match.index);
        }
        return pos;
    }
    
    alert( getSelectFrom(str) );
    

3 个答案:

答案 0 :(得分:3)

以下是Matching Nested Constructs in JavaScript, Part 2的可能解决方案。

使用示例:

keys   = ['key1', 'key1', 'key1', 'key1', 'key2', 'key2', 'key2', 'key2']
values = ['PTRG0097', 'CPOG0893', 'MMUG0444', 'BTAG0783', 'CPOG0893', 'MMUG0444', 'PPYG0539', 'BTAG0083']

&#13;
&#13;
matchRecursiveRegExp("START text START text END text more END text", "START", "END");
&#13;
&#13;
&#13;

答案 1 :(得分:0)

我很难理解你究竟想要什么,但如果我理解正确:你不能用javascript中的纯正则表达式做到这一点,因为lookbehind(正(?<=...)和负(?<!...))不是支持,因此您无法在匹配结果之前匹配'start(n)'。

但您可以使用子组(javascript中不完全支持子组,因此您需要使用替换):

var string = "something start(1) something_needed end(1) something";
var regex = /start\((\d+)\)(.*)end\(\1\)/;
string.replace(regex, function($0, $1, $2) {

    var result = $2;
    console.log($2)
    //do stuff with $2 here
});

$ 0是原始匹配(start\((\d+)\)(.*)end\(\1\)

$ 1和$ 2是正则表达式输出的组。

$ 1指的是(\d+)。它已经用于“存储”开头后面的数字(在这种情况下为1)。但是这里发生了魔法:它再次被加载并与正则表达式中的\1匹配。

$ 2是您存储所需信息的地方。它指的是(.*)

答案 2 :(得分:0)

您正在寻找的是找到&#39;开始&#39;计算另一个开始的次数&#39;找到,然后忽略等量的结束。这是使用正则表达式无法完成的事情。

无法比较2个字符串与纯正则表达式匹配的次数。

相反,这里有几个针对此问题的半正则表达式解决方案:

    var string = "start(1) something start(2) start(3) something end(3) something start(4) end(4) something end(2) something end(1) something start(5) something end(5)";
var stop;
do {
    stop = true;
    string = string.replace(/start((?:[^s]|s(?!tart))*?)end/, function($0, $1) {
         stop = false;
         var result = $1;

         //do stuff with result here..
         console.log(result);

         return ""; //replaces the match with empty so it can continue processing
    });
} while (!stop);

这个方法的好处很简单,你可以拥有无​​限数量的嵌套语句。