我有字符串,我想在其中找到2个字:'开始'和'结束'。
'开始'和'结束'总是聚集在一起(也许我会在他们之间有另一个角色,但如果我有'开始 ',我也会'结束'。
我尝试使用regEx源找到第一个'开始'而不是他自己的'结束',它会返回正确的子字符串。
字符串的例子: [我在这个例子索引中为每一对'开始'和'结束'写了只是为了清晰(在真正的字符串中我不会有这个索引) - 答案总是在index(1)]
之间// print 'something_needed'
// print 'something start(2) something end(2) something'
// print 'something start**(2) start(3) something end(3) something start(4) end(4) something end(2) something'
这是我在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) );
答案 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']
matchRecursiveRegExp("START text START text END text more END text", "START", "END");
&#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);
这个方法的好处很简单,你可以拥有无限数量的嵌套语句。