/(?<=.*)(\w\w)(?=.*)/ 没有给出我所期望的

/(?<=.*)(\w\w)(?=.*)/ not giving what I would expect

我正在浏览器的控制台中尝试以下正则表达式 /(?<=.*)(\w\w)(?=.*)/

我按如下方式阅读此正则表达式:“查找并捕获任何两个字母数字字符,前后出现零次或多次出现的任何字符”。

将“abcde”作为输入,我希望我的浏览器能够匹配“ab”、“bc”、“cd”和“de”。

为什么它只给我“ab”和“cd”?

有没有办法制作一个正则表达式 return 我想要的所有匹配项(“ab”、“bc”、“cd”和“de”)?

我知道环顾四周的用途,而且我已经看过 How does the regular expression ‘(?<=#)[^#]+(?=#)’ work?。 自 2018-2019 年以来,Google Chrome 支持 Lookbehind。

提前致谢

  1. /(?<=.*)(\w\w)(?=.*)//(\w\w)/ 相同,因为“前后有零次或多次出现”在任何情况下总是匹配(因为它匹配空字符串)。

  2. 不同于零长度断言(\b$(?=)等),所有其他表达式是 非零长度 ,即它们从字符串中消耗了一部分长度。有一些搜索游标会按此长度前进并且永远不会后退。如果找到 2 个符号,则此游标前进 2 个符号,并继续搜索。

对于所描述的行为,您需要像这样手动移动此光标:

const str = 'abcde';

const re = /(\w\w)/g;

let result;

while (result = re.exec(str)) {
  console.log(result);
  re.lastIndex--;
}

因此,为了找到重叠的匹配项,您必须将所需的模式放在前瞻中。

(?=(\w\w))

Regex DEMO

示例:

const regex = /(?=(\w\w))/gm;
const str = `abcde`;
let m;
let matches = [];

while ((m = regex.exec(str)) !== null) {
    // This is necessary to avoid infinite loops with zero-width matches
    if (m.index === regex.lastIndex) {
        regex.lastIndex++;
    }
    
    // The result can be accessed through the `m`-variable.
    m.forEach((match, groupIndex) => {
        if (groupIndex === 1) {
         matches.push(match);
        }
    });
}
console.log(matches);