Javascript Regex-查找所有可能的匹配项,即使在已经捕获的匹配项中也是如此
Javascript Regex - Find all possible matches, even in already captured matches
我正试图使用正则表达式和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
需要是两个匹配的一部分。
在不修改正则表达式的情况下,您可以使用.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的更新代码少了一点,执行速度也快了一点。=]
您无法从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
,它做了额外无用的替换工作。
不幸的是,它并不像单个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]
都匹配时取出匹配的字符串。
- 用于查找子字符串的Regex
- RegEx查找4位数字前后的逗号
- Javascript Regex,在字符串中查找数字
- 使用Regex查找URL中的特定字符串
- Regex查找前面没有特定字符的字符
- 使用regex从巨大的html表中查找某些td值
- 使用jquery查找regex匹配的元素
- regex:查找所有未注释的标记
- Java Script Regex-查找脚本中是否只有允许的字符
- Regex以查找除输入的最后n个字符之外的匹配项
- Regex查找用方括号括起来的单个单词
- JS regex.exec() 返回第一个查找
- 使用 RegEx 查找 HTML 标记之间的内容
- Regex查找<a>包含指向特定文件类型的链接的标记
- Node.js regex:在样式表中查找所有CSS属性,而不是在注释中
- 用Javascript regex在一行中查找表达式,然后将其追加到该行的末尾
- java脚本regex.match只查找一个结果
- 正在查找Regex链接中尚未包含的字符串
- 查找regex:软连字符或非单词字符
- 查找Regex Word的最后一次出现