642

I am after documentation on using wildcard or regular expressions (not sure on the exact terminology) with a jQuery selector.

I have looked for this myself but have been unable to find information on the syntax and how to use it. Does anyone know where the documentation for the syntax is?

EDIT: The attribute filters allow you to select based on patterns of an attribute value.

John Slegers
  • 45,213
  • 22
  • 199
  • 169
Joel Cunningham
  • 13,620
  • 8
  • 43
  • 49

10 Answers10

770

You can use the filter function to apply more complicated regex matching.

Here's an example which would just match the first three divs:

$('div')
  .filter(function() {
    return this.id.match(/abc+d/);
  })
  .html("Matched!");
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div id="abcd">Not matched</div>
<div id="abccd">Not matched</div>
<div id="abcccd">Not matched</div>
<div id="abd">Not matched</div>
daaawx
  • 3,273
  • 2
  • 17
  • 16
nickf
  • 537,072
  • 198
  • 649
  • 721
359

James Padolsey created a wonderful filter that allows regex to be used for selection.

Say you have the following div:

<div class="asdf">

Padolsey's :regex filter can select it like so:

$("div:regex(class, .*sd.*)")

Also, check the official documentation on selectors.

UPDATE: : syntax Deprecation JQuery 3.0

Since jQuery.expr[':'] used in Padolsey's implementation is already deprecated and will render a syntax error in the latest version of jQuery, here is his code adapted to jQuery 3+ syntax:

jQuery.expr.pseudos.regex = jQuery.expr.createPseudo(function (expression) {
    return function (elem) {
        var matchParams = expression.split(','),
            validLabels = /^(data|css):/,
            attr = {
                method: matchParams[0].match(validLabels) ?
                    matchParams[0].split(':')[0] : 'attr',
                property: matchParams.shift().replace(validLabels, '')
            },
            regexFlags = 'ig',
            regex = new RegExp(matchParams.join('').replace(/^\s+|\s+$/g, ''), regexFlags);
        return regex.test(jQuery(elem)[attr.method](attr.property));
    }
});
Abilogos
  • 4,777
  • 2
  • 19
  • 39
Xenph Yan
  • 83,019
  • 16
  • 48
  • 55
  • 3
    Ok. I have been there but I didn't really know the name of what I was looking for. Ive had another look and using attribute filters is what I was after. – Joel Cunningham Oct 10 '08 at 05:49
  • The regex selector by @padolsey works great. Here's an example where you can iterate over text, file and checkbox input fields or textareas with it: $j('input:regex(type, text|file|checkbox),textarea').each(function(index){ // ... }); – Matthew Setter Jan 06 '12 at 11:41
  • @Xenph Does this filter allow backreferencing matched data inside of a callback function? – aborted Jan 03 '14 at 16:30
  • 17
    The answer below from nickf should be the accepted one. If you are reading this answer, be sure to read that one! – Quentin Skousen Sep 17 '14 at 19:58
  • 6
    I'm getting Error: Syntax error, unrecognized expression: unsupported pseudo: regex – ryan2johnson9 Jan 29 '15 at 00:15
  • 2
    -1. The code to implement this is not included in the answer and is susceptible to link rot. Additionally, I found two bugs while testing the code - it will drop commas from regular expressions containing them (solved by replacing `matchParams.join('')` with `matchParams.join(',')`), and any pattern that matches `'undefined'` or `'null'` will match `undefined` and `null`, respectively. This second bug can be solved by checking that the tested value `!== undefined` and `!== null` first. Either way, passing a function into `.filter()` is easier and feels cleaner / more readable to me. – James T Mar 02 '18 at 22:49
352

These can be helpful.

If you're finding by Contains then it'll be like this

    $("input[id*='DiscountType']").each(function (i, el) {
         //It'll be an array of elements
     });

If you're finding by Starts With then it'll be like this

    $("input[id^='DiscountType']").each(function (i, el) {
         //It'll be an array of elements
     });

If you're finding by Ends With then it'll be like this

     $("input[id$='DiscountType']").each(function (i, el) {
         //It'll be an array of elements
     });

If you want to select elements which id is not a given string

    $("input[id!='DiscountType']").each(function (i, el) {
         //It'll be an array of elements
     });

If you want to select elements which name contains a given word, delimited by spaces

     $("input[name~='DiscountType']").each(function (i, el) {
         //It'll be an array of elements
     });

If you want to select elements which id is equal to a given string or starting with that string followed by a hyphen

     $("input[id|='DiscountType']").each(function (i, el) {
         //It'll be an array of elements
     });
dnxit
  • 7,118
  • 2
  • 30
  • 34
  • 5
    Great answer, but `id`s, being identifiers, [can't contain a space](https://www.w3.org/TR/CSS21/syndata.html#value-def-identifier), the `~=` example should be changed to something else, like `class`, which is a white-space delimited list of identifiers. Things like `class` are what the `~=` attribute selector was intended for. – Useless Code Sep 25 '16 at 14:29
63

If your use of regular expression is limited to test if an attribut start with a certain string, you can use the ^ JQuery selector.

For example if your want to only select div with id starting with "abc", you can use:

$("div[id^='abc']")

A lot of very useful selectors to avoid use of regex can be find here: http://api.jquery.com/category/selectors/attribute-selectors/

johannchopin
  • 13,720
  • 10
  • 55
  • 101
Nicolas Janel
  • 3,025
  • 1
  • 28
  • 31
  • this won't work for case insensitive matches requirements. The .filter function better fits those needs. – brainondev Aug 21 '14 at 11:25
  • 3
    this was good for me, I just wanted to see if there was a '__destroy' on the end of an input id so I used `*=` like this: `$("input[id*='__destroy'][value='true']")` – ryan2johnson9 Jan 29 '15 at 00:25
25
var test = $('#id').attr('value').match(/[^a-z0-9 ]+/);

Here you go!

Makyen
  • 31,849
  • 12
  • 86
  • 121
Kamil Dąbrowski
  • 984
  • 11
  • 17
9

Add a jQuery function,

(function($){
    $.fn.regex = function(pattern, fn, fn_a){
        var fn = fn || $.fn.text;
        return this.filter(function() {
            return pattern.test(fn.apply($(this), fn_a));
        });
    };
})(jQuery);

Then,

$('span').regex(/Sent/)

will select all span elements with text matches /Sent/.

$('span').regex(/tooltip.year/, $.fn.attr, ['class'])

will select all span elements with their classes match /tooltip.year/.

brook hong
  • 573
  • 6
  • 13
7

ids and classes are still attributes, so you can apply a regexp attribute filter to them if you select accordingly. Read more here: http://rosshawkins.net/archive/2011/10/14/jquery-wildcard-selectors-some-simple-examples.aspx

Jim
  • 1,499
  • 1
  • 24
  • 43
Jānis Elmeris
  • 1,975
  • 1
  • 25
  • 43
2
$("input[name='option[colour]'] :checked ")
Bill the Lizard
  • 398,270
  • 210
  • 566
  • 880
2

I'm just giving my real time example:

In native javascript I used following snippet to find the elements with ids starts with "select2-qownerName_select-result".

document.querySelectorAll("[id^='select2-qownerName_select-result']");

When we shifted from javascript to jQuery we've replaced above snippet with the following which involves less code changes without disturbing the logic.

$("[id^='select2-qownerName_select-result']")

Vishnu Prasanth G
  • 1,133
  • 12
  • 12
1

If you just want to select elements that contain given string then you can use following selector:

$(':contains("search string")')

Prakash GPz
  • 1,675
  • 4
  • 16
  • 27