Respond.js comment regex vs. parser (v2)

Revision 2 of this benchmark created on


Preparation HTML

<script>
  var styles = '@media screen and (min-width: 960px) {body{min-width:960px}.container-12,.container-16{margin-left:auto;margin-right:auto;width:960px}.grid-1,.grid-2,.grid-3,.grid-4,.grid-5,.grid-6,.grid-7,.grid-8,.grid-9,.grid-10,.grid-11,.grid-12,.grid-13,.grid-14,.grid-15,.grid-16{display:inline;float:left;margin-left:10px;margin-right:10px}.push-1,.pull-1,.push-2,.pull-2,.push-3,.pull-3,.push-4,.pull-4,.push-5,.pull-5,.push-6,.pull-6,.push-7,.pull-7,.push-8,.pull-8,.push-9,.pull-9,.push-10,.pull-10,.push-11,.pull-11,.push-12,.pull-12,.push-13,.pull-13,.push-14,.pull-14,.push-15,.pull-15{position:relative}.container-12 .grid-3,.container-16 .grid-4{width:220px}.container-12 .grid-6,.container-16 .grid-8{width:460px}.container-12 .grid-9,.container-16 .grid-12{width:700px}.container-12 .grid-12,.container-16 .grid-16{width:940px}.alpha{margin-left:0}.omega{margin-right:0}.container-12 .grid-1{width:60px}.container-12 .grid-2{width:140px}.container-12 .grid-4{width:300px}.container-12 .grid-5{width:380px}.container-12 .grid-7{width:540px}.container-12 .grid-8{width:620px}.container-12 .grid-10{width:780px}.container-12 .grid-11{width:860px}.container-16 .grid-1{width:40px}.container-16 .grid-2{width:100px}.container-16 .grid-3{width:160px}.container-16 .grid-5{width:280px}.container-16 .grid-6{width:340px}.container-16 .grid-7{width:400px}.container-16 .grid-9{width:520px}.container-16 .grid-10{width:580px}.container-16 .grid-11{width:640px}.container-16 .grid-13{width:760px}.container-16 .grid-14{width:820px}.container-16 .grid-15{width:880px}.container-12 .prefix-3,.container-16 .prefix-4{padding-left:240px}.container-12 .prefix-6,.container-16 .prefix-8{padding-left:480px}.container-12 .prefix-9,.container-16 .prefix-12{padding-left:720px}.container-12 .prefix-1{padding-left:80px}.container-12 .prefix-2{padding-left:160px}.container-12 .prefix-4{padding-left:320px}.container-12 .prefix-5{padding-left:400px}.container-12 .prefix-7{padding-left:560px}.container-12 .prefix-8{padding-left:640px}.container-12 .prefix-10{padding-left:800px}.container-12 .prefix-11{padding-left:880px}.container-16 .prefix-1{padding-left:60px}.container-16 .prefix-2{padding-left:120px}.container-16 .prefix-3{padding-left:180px}.container-16 .prefix-5{padding-left:300px}.container-16 .prefix-6{padding-left:360px}.container-16 .prefix-7{padding-left:420px}.container-16 .prefix-9{padding-left:540px}.container-16 .prefix-10{padding-left:600px}.container-16 .prefix-11{padding-left:660px}.container-16 .prefix-13{padding-left:780px}.container-16 .prefix-14{padding-left:840px}.container-16 .prefix-15{padding-left:900px}.container-12 .suffix-3,.container-16 .suffix-4{padding-right:240px}.container-12 .suffix-6,.container-16 .suffix-8{padding-right:480px}.container-12 .suffix-9,.container-16 .suffix-12{padding-right:720px}.container-12 .suffix-1{padding-right:80px}.container-12 .suffix-2{padding-right:160px}.container-12 .suffix-4{padding-right:320px}.container-12 .suffix-5{padding-right:400px}.container-12 .suffix-7{padding-right:560px}.container-12 .suffix-8{padding-right:640px}.container-12 .suffix-10{padding-right:800px}.container-12 .suffix-11{padding-right:880px}.container-16 .suffix-1{padding-right:60px}.container-16 .suffix-2{padding-right:120px}.container-16 .suffix-3{padding-right:180px}.container-16 .suffix-5{padding-right:300px}.container-16 .suffix-6{padding-right:360px}.container-16 .suffix-7{padding-right:420px}.container-16 .suffix-9{padding-right:540px}.container-16 .suffix-10{padding-right:600px}.container-16 .suffix-11{padding-right:660px}.container-16 .suffix-13{padding-right:780px}.container-16 .suffix-14{padding-right:840px}.container-16 .suffix-15{padding-right:900px}.container-12 .push-3,.container-16 .push-4{left:240px}.container-12 .push-6,.container-16 .push-8{left:480px}.container-12 .push-9,.container-16 .push-12{left:720px}.container-12 .push-1{left:80px}.container-12 .push-2{left:160px}.container-12 .push-4{left:320px}.container-12 .push-5{left:400px}.container-12 .push-7{left:560px}.container-12 .push-8{left:640px}.container-12 .push-10{left:800px}.container-12 .push-11{left:880px}.container-16 .push-1{left:60px}.container-16 .push-2{left:120px}.container-16 .push-3{left:180px}.container-16 .push-5{left:300px}.container-16 .push-6{left:360px}.container-16 .push-7{left:420px}.container-16 .push-9{left:540px}.container-16 .push-10{left:600px}.container-16 .push-11{left:660px}.container-16 .push-13{left:780px}.container-16 .push-14{left:840px}.container-16 .push-15{left:900px}.container-12 .pull-3,.container-16 .pull-4{left:-240px}.container-12 .pull-6,.container-16 .pull-8{left:-480px}.container-12 .pull-9,.container-16 .pull-12{left:-720px}.container-12 .pull-1{left:-80px}.container-12 .pull-2{left:-160px}.container-12 .pull-4{left:-320px}.container-12 .pull-5{left:-400px}.container-12 .pull-7{left:-560px}.container-12 .pull-8{left:-640px}.container-12 .pull-10{left:-800px}.container-12 .pull-11{left:-880px}.container-16 .pull-1{left:-60px}.container-16 .pull-2{left:-120px}.container-16 .pull-3{left:-180px}.container-16 .pull-5{left:-300px}.container-16 .pull-6{left:-360px}.container-16 .pull-7{left:-420px}.container-16 .pull-9{left:-540px}.container-16 .pull-10{left:-600px}.container-16 .pull-11{left:-660px}.container-16 .pull-13{left:-780px}.container-16 .pull-14{left:-840px}.container-16 .pull-15{left:-900px}.clear{clear:both;display:block;overflow:hidden;visibility:hidden;width:0;height:0}.clearfix:before,.clearfix:after{content:\'\0020\';display:block;overflow:hidden;visibility:hidden;width:0;height:0}.clearfix:after{clear:both}.clearfix{zoom:1}}/*/mediaquery*/';
  
  var parseMQs = function(str) {
   var index = 0,
       arr = str.split(''),
       len = arr.length,
       stack = [],
       media = [],
       queries = [],
       inMediaQuery = false;
  
   while (index < len) {
    switch (arr[index]) {
     // Start of a block.
    case '{':
     stack.push('{');
     if (stack.length === 2) {
      inMediaQuery = true;
     }
     break;
  
     // End of a block.
    case '}':
     stack.pop();
     if (stack.length === 0 && inMediaQuery) {
      if (media.length) {
       queries.push(str.substring(media.pop(), index));
      }
      inMediaQuery = false;
     }
     break;
  
     // @media queries.
    case '@':
     if (str.substring(index, index + 7) === '@media ') {
      var start = index;
      // Zip forward to the start of the media query.
      while (++index < len && arr[index] !== '{');
  
      // Save the location of this media query.  If we hit the end of the file
      // just fucking, i don't know.
      if (str[index] === '{') {
       media.push(start);
       index--;
      }
     }
     break;
  
     // Doubley quoted strings.
    case '"':
     while (++index < len && arr[index] !== '"');
     break;
  
     // Singley quoted strings.
    case "'":
     while (++index < len && arr[index] !== "'");
     break;
  
     // Comments.
    case "/":
     if (arr[index + 1] == '*') {
      index += 2;
      // Zip to the end of this comment block.
      while (++index < len && arr[index] !== '/' && arr[index - 1] !== '*');
     }
     break;
    };
  
    index++;
   }
  
   return queries;
  };
  
  console.log(styles.match(/@media ([^\{]+)\{((?!@media)[\s\S])*(?=\}[\s]*\/\*\/mediaquery\*\/)/gmi));
  console.log(parseMQs(styles));
</script>

Test runner

Ready to run.

Testing in
TestOps/sec
Comment Regex
styles.match(/@media ([^\{]+)\{((?!@media)[\s\S])*(?=\}[\s]*\/\*\/mediaquery\*\/)/gmi);
ready
Parser
parseMQs(styles);
ready

Revisions

You can edit these tests or add more tests to this page by appending /edit to the URL.