Edit in JSFiddle

(function($) {

  /* by Elijah Manor    
   * Filter results by html5 data attributes either at design-time 
   * ( HTML5 data-attr ) or at runtime ( internal jQuery data() )
   *
   * Usages
   * $( "p:dataAttr(mytype)" )   // returns all p's with data mytype attr
   * $( "p:dataAttr(my, ^=)" )   // returns all p's that start with data myty attr
   * $( "p:dataAttr(type, $=)" ) // returns all p's that ends with data myty attr
   * $( "p:dataAttr(yty, ~=)" )  // returns all p's that contains data myty attr
    */
  $.expr[ ":" ].dataAttr = function( element, index, match, array ) {
    var parameters = match[ 3 ].split( "," ),
        attr = $.trim( parameters[0] ),
        compare = $.trim( parameters[1] ) || "=", 
        data = $( element ).data(),
        matches = false;
      
    $.each( data, function( key, _ ) {
      index = key.indexOf( attr );
      
      if ( compare === "=" ) {
        matches = key === attr; 
      } else if ( compare === "^=" ) {
        matches = index === 0; 
      } else if ( compare === "$=" ) {
        matches = ~index && index === ( key.length - attr.length );  
      } else if ( compare === "~=" ) {
        matches = !!~index;
      }
      
      if ( matches ) { return false; }
    });
       
    return matches; 
  };
    
})(jQuery);

pavlov.specify.globalApi = true;
pavlov.specify( "jQuery :dataAttr Pseudo Selector", function() {

  var $fixture = $( "#qunit-fixture" );
    
  describe( "Design-time Checks", function() {

    it( "should not match an element that doesn't have the data-attr", function() {
        var $p = $( "p:dataAttr(bogus)" );
      
      assert( $p ).isDefined();        
      assert( $p.length ).isEqualTo( 0 );
    });
    
    it( "should match an element that has a data-attr", function() {
        var $p = $( "p:dataAttr(mytype)" );
      
      assert( $p ).isDefined();        
      assert( $p.length ).isEqualTo( 1 );
      assert( $p.index() ).isEqualTo( 6 );
    });

    it( "should match an element that starts with a data-attr", function() {
        var $p = $( "p:dataAttr(my, ^=)" );
      
      assert( $p ).isDefined();        
      assert( $p.length ).isEqualTo( 5 );        
    });  
   
    it( "should match an element that ends with a data-attr", function() {
        var $p = $( "p:dataAttr(type, $=)" );
      
      assert( $p ).isDefined();        
      assert( $p.length ).isEqualTo( 1 );
      assert( $p.index() ).isEqualTo( 6 );        
    });      

    it( "should match an element that contains a data-attr", function() {
        var $p = $( "p:dataAttr(type, ~=)" );
      
      assert( $p ).isDefined();        
      assert( $p.length ).isEqualTo( 2 );
      assert( $p.eq( 0 ).index() ).isEqualTo( 6 );        
      assert( $p.eq( 1 ).index() ).isEqualTo( 7 );        
    });      
      
  });
  
  describe( "Run-time Checks", function() {

    it( "should not match an element that doesn't have data key", function() {
      var $runtime = $( "p.runtime" ).data( "runtype", "" ),
          $p = $( "p:dataAttr(runtype)" );
              
      assert( $p ).isDefined();    
      assert( $p.length ).isEqualTo( 1 );        
    });
      
    it( "should match an element that has data key with value of empty string", function() {
      var $runtime = $( "p.runtime" ).data( "runtype", "" ),
          $p = $( "p:dataAttr(runtype)" );
              
      assert( $p ).isDefined();    
      assert( $p.length ).isEqualTo( 1 );        
    });

    it( "should match an element that has a data key with value of non-empty string", function() {
      var $runtime = $( "p.runtime" ).data( "runtype", "hello" ),
          $p = $( "p:dataAttr(runtype)" );
              
      assert( $p ).isDefined();    
      assert( $p.length ).isEqualTo( 1 );        
    });  
         
    it( "should match an element with data key starts with", function() {
      var $runtime = $( "p.runtime" ).data( "runtype", "hello" ),
          $p = $( "p:dataAttr(run, ^=)" );
      
      assert( $p ).isDefined();        
      assert( $p.length ).isEqualTo( 1 );        
      assert( $p.index() ).isEqualTo( 1 );        
    });  
   
    it( "should match an element with data key ends with", function() {
      var $runtime = $( "p.runtime" ).data( "runtype", "hello" ),
          $p = $( "p:dataAttr(ntype, $=)" );
      
      assert( $p ).isDefined();        
      assert( $p.length ).isEqualTo( 1 );
      assert( $p.index() ).isEqualTo( 1 );        
    });      

    it( "should match an element with data key contains", function() {
      var $runtime = $( "p.runtime" ).data( "runtype", "hello" ),
          $p = $( "p:dataAttr(unt, ~=)" );
      
      assert( $p ).isDefined();        
      assert( $p.length ).isEqualTo( 1 );
      assert( $p.index() ).isEqualTo( 1 );        
    });      
      
  });
  
});