Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/472.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript正则表达式-查找所有可能的匹配项,即使是在已捕获的匹配项中_Javascript_Regex_String_Match - Fatal编程技术网

Javascript正则表达式-查找所有可能的匹配项,即使是在已捕获的匹配项中

Javascript正则表达式-查找所有可能的匹配项,即使是在已捕获的匹配项中,javascript,regex,string,match,Javascript,Regex,String,Match,我正在尝试使用带有javascript的正则表达式从字符串中获取所有可能的匹配项。似乎我的方法是不匹配已经匹配的字符串部分 变量: var字符串='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 A1B

我正在尝试使用带有javascript的正则表达式从字符串中获取所有可能的匹配项。似乎我的方法是不匹配已经匹配的字符串部分

变量:

var字符串='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
需要是两个匹配项的一部分。

在不修改正则表达式的情况下,您可以使用并操作正则表达式对象的
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的更新代码少了一点,性能也稍差
=]

您无法从
match
获得直接结果,但可以通过
RegExp.exec
生成结果,并对regex进行一些修改:

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
,因此它会进行额外的无用的替换工作。

不幸的是,它并不像单个
字符串那样简单。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"
];
。打开控制台查看结果


或者,您可以在
上拆分原始字符串,然后在生成的数组中循环,当
数组[i]
数组[i+1]
都匹配时,拉出匹配的字符串。

先行将获得您想要的匹配,但不幸的是,它没有返回先行部分。我还没有找到一种用javascript捕获前瞻的方法。也许有,我不知道。带有前瞻的正则表达式是:var reg=/A[0-9]+B[0-9]+Y(?=:A[0-9]+B[0-9]+Y)/g@Mantriur:看到我的答案了吧……也许
string.split(“:”)
然后在数组上循环可能会给你一个更好的结果。@nhahtdh用match()尝试了这个方法,但当然,前瞻是一个单独的捕获。哼!漂亮的答案。:-)很好,这比前瞻、捕获组等要好得多。顺便说一句,
reg.lastIndex=found.index+1应该足够了,并使其成为表达式-agnostic@VinnieCent没问题<代码>=]
勾选向上/向下箭头下方的V,如果对您有效,则将其标记为已接受。哦,谢谢你,Bergi,我不知道那房子<代码>x]我必须执行reg.lastIndex=found.index+found[0]。长度;因此,它将从上次匹配后的位置继续。请注意:如果未为RegExp设置全局(“g”)标志,则此操作将不起作用。(
newregexp(“foo”,“g”)
/foo/g