How can I match overlapping strings with regex?

后端 未结 6 1843
猫巷女王i
猫巷女王i 2020-11-22 03:27

Let\'s say I have the string

\"12345\"

If I .match(/\\d{3}/g), I only get one match, \"123\". Why don\'t I get

6条回答
  •  我寻月下人不归
    2020-11-22 03:32

    To answer the "How", you can manually change the index of the last match (requires a loop) :

    var input = '12345', 
        re = /\d{3}/g, 
        r = [], 
        m;
    while (m = re.exec(input)) {
        re.lastIndex -= m[0].length - 1;
        r.push(m[0]);
    }
    r; // ["123", "234", "345"]
    

    Here is a function for convenience :

    function matchOverlap(input, re) {
        var r = [], m;
        // prevent infinite loops
        if (!re.global) re = new RegExp(
            re.source, (re+'').split('/').pop() + 'g'
        );
        while (m = re.exec(input)) {
            re.lastIndex -= m[0].length - 1;
            r.push(m[0]);
        }
        return r;
    }
    

    Usage examples :

    matchOverlap('12345', /\D{3}/)      // []
    matchOverlap('12345', /\d{3}/)      // ["123", "234", "345"]
    matchOverlap('12345', /\d{3}/g)     // ["123", "234", "345"]
    matchOverlap('1234 5678', /\d{3}/)  // ["123", "234", "567", "678"]
    matchOverlap('LOLOL', /lol/)        // []
    matchOverlap('LOLOL', /lol/i)       // ["LOL", "LOL"]
    

提交回复
热议问题