Unfortunately all other answers are wrong , have managed the wildcard / wildcard behavior, but did not understand that the behavior has to be like selector .classe
, so as it is in CSS2, CSS2.1 and CSS2.2
Both the .classe
selector and the [atributo~=valor]
attribute selector do not behave like normal attribute selectors , I explained it and I checked it well in the question at this point:
Note: The selector per point ( .
) does not only get attributes like <div class="foo">
, it also takes <div class="alpha foo betha">
, that is, it takes the attribute divided by "space". More details on link
Aliais follows the basic documentation link for those learning CSS and wants to understand the differences (or confirm what I say):
The solution
To make a selector that behaves like the class selector (or this [atributo~=valor]
selector) of the CSS with wildcard character similar to %
of LIKE
in Mysql
The solution I came up with will behave like .class
or how, it looks like this:
//Seletor customizado
jQuery.expr[':']['class-wildcard'] = function (elem, index, match) {
//Separa as partes da string
var parse = $.trim(match[3]).split('?');
//Escapa os caracteres necessários
for (var i = 0, j = parse.length; i < j; ++i) {
parse[i] = parse[i].replace(/[-\][*+?)(:\]/g, '\$&');
}
// Gera a regex em formato de string
var cls = '\b' + parse.join('\S+') + '\b';
return new RegExp(cls).test(elem.className);
};
console.log(":class-wildcard(js-use-?) -> ", $(":class-wildcard(js-use-?)").length);
console.log(":class-wildcard(foo?bar) -> ", $(":class-wildcard(foo?bar)").length);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script><!--abaixoserácomoseletor:class-wildcard(js-use-?)--><divclass="foo js-use-1"></div> <!-- será pego -->
<div class="js-use-2 bar"></div> <!-- será pego -->
<div class="baz js-use-3 boo"></div> <!-- será pego -->
<div class="js-use-empty"></div> <!-- será pego -->
<div class="foo wjs-use-1"></div> <!-- NÃO será pego -->
<div class="xjs-use-2 bar"></div> <!-- NÃO será pego -->
<div class="baz yjs-use-3 boo"></div> <!-- NÃO será pego -->
<div class="zjs-use-empty"></div> <!-- NÃO será pego -->
<!-- abaixo será com o seletor :class-wildcard(foo?bar) -->
<div class="foobazbar"></div> <!-- será pego -->
<div class="fooxyzbar"></div> <!-- será pego -->
<div class="fooabcbar"></div> <!-- será pego -->
<div class="col1 foobazbar"></div> <!-- será pego -->
<div class="col2 fooxyzbar custom"></div> <!-- será pego -->
<div class="fooabcbar col3"></div> <!-- será pego -->
<div class="fooar col4"></div> <!-- NÃO será pego -->
Explaining the code
To better explain the code, parse divides strings into arrays like this:
-
js-use-?
turns ["js-use", ""]
-
foo?bar
turns ["foo", "bar"]
This way you can apply "escape" to characters that could affect the regex occurring within for()
:
parse[i] = parse[i].replace(/[-\][*+?)(:\]/g, '\$&');
So then it joins with .join
the arrays again using as a separator the \S+
which will be the wildcard in this case, the expression \S
("s" in upper case) is the negation of \s
ie the wildcard can be anything but space, tab or line break.
Note that we also used \b
on the ends, an expression like this:
\bfoobar\b
It would be "similar" to this:
(^|\s)foobar($|\s)
That is, the value tested in the regex should begin and end with the expression word, or should contain spaces.
Then after join
the parameters would have results like this:
-
js-use-?
flip this regex /\bjs-use-\S+\b/
-
foo?bar
flip this regex /\bfoo\S+bar\b/
-
a?b?cde?xyz?
flip this regex /\ba\S+b\S+cde\S+xyz\S+\b/