JordyvD
JordyvD

Reputation: 1615

Javascript regex unexpected output

I'm trying to use node to do some regex on a css file.

Here's my javascript:

var fs = require ('fs');

fs.readFile('test.css','utf8',function(error,css){
if(error){
    console.log("I'm sorry, something went terribly wrong :o Here's the message: "+error);
}



var matches = css.match(/([a-zA-Z-]+):\s*([0-9]+)(vh|VH|vw|VW)/g);

    console.log(matches[2][1]);



});

Expected output when I run it:

regex101 output

Actual output: actual output

As you can see it does not put every match in its own array as expected, it just puts everything in one giant array without any sub-arrays. Anything I can do?

Upvotes: 1

Views: 83

Answers (4)

Viktor Kireev
Viktor Kireev

Reputation: 1240

It's actually expected behaviour. If you use string.match method with global flag, parenthesis do not create groups inside matches:

var str = "javascript is cool";
var result = str.match( /JAVA(SCRIPT)/g );
console.log( result[0] ); // javascript
console.log( result.length ); //1

Your case is using regexp.exec(str). It can find all matches and parenthesis groups in it.

var str = 'javascript is cool. Use javascript';

var regexp = /java(script)/g;

while (result = regexp.exec(str)) {   
  console.log(result.length);   //2
  console.log(result[0]);  //javascript
  console.log(result[1]);  //script 
} 

Upvotes: 1

stdob--
stdob--

Reputation: 29172

var reg = /([a-zA-Z-]+):\s*([0-9]+)(vh|VH|vw|VW)/g;
var matches = [];
var m;

while ((m = reg.exec(css)) !== null) {
    if (m.index === reg.lastIndex) {
        reg.lastIndex++;
    }
    matches.push(m);
}

console.log(matches);

Upvotes: 1

JordyvD
JordyvD

Reputation: 1615

Based on above answers I managed to come up with the following code:

while(match = css.match(/([a-zA-Z-]+):\s*([0-9]+)(vh|VH|vw|VW)/)){
        matches.push(match);
        css = css.replace(match[0],'');
}

Thanks a ton for the help everyone!

Upvotes: 0

Matt Zeunert
Matt Zeunert

Reputation: 16561

match doesn't give you the detailed match results in this case:

If the regular expression includes the g flag, the method returns an Array containing all matched substrings rather than match objects.

You can use exec instead:

var regex = /([a-zA-Z-]+):\s*([0-9]+)(vh|VH|vw|VW)/g;
var css = "body{\nfont-size: 10vw;\n height: 500vh\n}";
var match;

while (match = r.exec(css)){
    console.log(match)
}

Which gives this output:

["font-size: 10vw", "font-size", "10", "vw", index: 6, input: "body{↵font-size: 10vw;↵ height: 500vh↵}"]  
["height: 500vh", "height", "500", "vh", index: 24, input: "body{↵font-size: 10vw;↵ height: 500vh↵}"]

Upvotes: 1

Related Questions