正则表达式的Javascript - 查找所有可能的匹配,即使在已经拍摄的比赛正则表达式的Java

2019-05-12 01:58发布

我试图获得使用正则表达式的JavaScript字符串所有可能的匹配 。 看来,我这样做的方法是不匹配已经被匹配的字符串部分。

变量:

var string = 'A1B1Y:A1B2Y:A1B3Y:A1B4Z:A1B5Y:A1B6Y:A1B7Y:A1B8Z:A1B9Y:A1B10Y:A1B11Y';

var reg = /A[0-9]+B[0-9]+Y:A[0-9]+B[0-9]+Y/g;

码:

var match = string.match(reg);

所有匹配的结果我得到:

A1B1Y:A1B2Y
A1B5Y:A1B6Y
A1B9Y:A1B10Y

匹配的结果我想:

A1B1Y:A1B2Y
A1B2Y:A1B3Y
A1B5Y:A1B6Y
A1B6Y:A1B7Y
A1B9Y:A1B10Y
A1B10Y:A1B11Y

在我的头上,我想A1B1Y:A1B2Y是沿比赛A1B2Y:A1B3Y ,即使A1B2Y字符串中将需要两场比赛的一部分。

Answer 1:

无需修改您正则表达式,你可以将其设置为开始使用在比赛下半场的每场比赛后开始匹配.exec和操纵的正则表达式对象的lastIndex财产。

var string = 'A1B1Y:A1B2Y:A1B3Y:A1B4Z:A1B5Y:A1B6Y:A1B7Y:A1B8Z:A1B9Y:A1B10Y:A1B11Y';
var reg = /A[0-9]+B[0-9]+Y:A[0-9]+B[0-9]+Y/g;
var matches = [], found;
while (found = reg.exec(string)) {
    matches.push(found[0]);
    reg.lastIndex -= found[0].split(':')[1].length;
}

console.log(matches);
//["A1B1Y:A1B2Y", "A1B2Y:A1B3Y", "A1B5Y:A1B6Y", "A1B6Y:A1B7Y", "A1B9Y:A1B10Y", "A1B10Y:A1B11Y"]

演示


按照BERGI的评论,你还可以获得最后一场比赛的索引和递增1,以便它,而不是开始从本场比赛的下半场开始匹配,它会开始尝试从每场比赛的第二个字符开始匹配:

reg.lastIndex = found.index+1;

演示

最终结果是一样的。 虽然,BERGI的更新少一些代码,并稍微执行速度更快 。 =]



Answer 2:

你不能得到直接的结果match ,但可以通过产生的结果RegExp.exec ,并与一些修改,正则表达式:

var regex = /A[0-9]+B[0-9]+Y(?=(:A[0-9]+B[0-9]+Y))/g;
var input = 'A1B1Y:A1B2Y:A1B3Y:A1B4Z:A1B5Y:A1B6Y:A1B7Y:A1B8Z:A1B9Y:A1B10Y:A1B11Y'
var arr;
var results = [];

while ((arr = regex.exec(input)) !== null) {
    results.push(arr[0] + arr[1]);
}

我用零宽度正先行(?=pattern)为了不消耗文本,从而使重叠部分可以被重新匹配。

其实,这是有可能滥用replace方法来完成实现相同的结果:

var input = 'A1B1Y:A1B2Y:A1B3Y:A1B4Z:A1B5Y:A1B6Y:A1B7Y:A1B8Z:A1B9Y:A1B10Y:A1B11Y'
var results = [];

input.replace(/A[0-9]+B[0-9]+Y(?=(:A[0-9]+B[0-9]+Y))/g, function ($0, $1) {
    results.push($0 + $1);
    return '';
});

但是,由于它是replace ,它额外的无用的更换工作。



Answer 3:

不幸的是,它并不像一个简单string.match

原因是,你想重叠的比赛,其中/g标志不给你。

你可以使用前瞻:

var re = /A\d+B\d+Y(?=:A\d+B\d+Y)/g;

但现在你会得到:

string.match(re); // ["A1B1Y", "A1B2Y", "A1B5Y", "A1B6Y", "A1B9Y", "A1B10Y"]

其原因是向前看是零宽度,也就是说,它只是说格局是否来自你想匹配或不追求的; 它不包括其在比赛中。

你可以使用exec ,试图抓住你想要的东西。 如果一个正则表达式有/g标志,你可以运行exec多次获得所有的比赛:

// using re from above to get the overlapping matches

var m;
var matches = [];
var re2 = /A\d+B\d+Y:A\d+B\d+Y/g; // make another regex to get what we need

while ((m = re.exec(string)) !== null) {
  // m is a match object, which has the index of the current match
  matches.push(string.substring(m.index).match(re2)[0]);
}

matches == [
  "A1B1Y:A1B2Y", 
  "A1B2Y:A1B3Y", 
  "A1B5Y:A1B6Y", 
  "A1B6Y:A1B7Y", 
  "A1B9Y:A1B10Y", 
  "A1B10Y:A1B11Y"
];

下面是这个动作小提琴 。 打开控制台来查看结果

或者,可以在分割原始字符串:通过将得到的数组循环,然后,拉出匹配的那些当array[i]array[i+1]双方比赛等你想要的。



文章来源: Javascript Regex - Find all possible matches, even in already captured matches