jQuery selector regular expressions
Asked Answered
B

10

646

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.

Billups answered 10/10, 2008 at 5:40 Comment(0)
M
361

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));
    }
});
Morehouse answered 10/10, 2008 at 5:41 Comment(6)
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.Billups
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){ // ... });Disburden
@Xenph Does this filter allow backreferencing matched data inside of a callback function?Ladybug
The answer below from nickf should be the accepted one. If you are reading this answer, be sure to read that one!Djerba
I'm getting Error: Syntax error, unrecognized expression: unsupported pseudo: regexBroek
-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.Acidophil
R
771

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>
Rudderhead answered 11/10, 2008 at 7:6 Comment(2)
how to use variables in the place of match(/abc+d/); ?Romanov
@Sasivarnakumar the answer for this question is hereGalvani
M
361

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));
    }
});
Morehouse answered 10/10, 2008 at 5:41 Comment(6)
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.Billups
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){ // ... });Disburden
@Xenph Does this filter allow backreferencing matched data inside of a callback function?Ladybug
The answer below from nickf should be the accepted one. If you are reading this answer, be sure to read that one!Djerba
I'm getting Error: Syntax error, unrecognized expression: unsupported pseudo: regexBroek
-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.Acidophil
P
355

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
     });
Proof answered 14/7, 2014 at 15:59 Comment(1)
Great answer, but ids, being identifiers, can't contain a space, 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.Cue
C
66

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/

Copyreader answered 5/11, 2013 at 11:43 Comment(2)
this won't work for case insensitive matches requirements. The .filter function better fits those needs.Cassiopeia
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']")Broek
C
25
var test = $('#id').attr('value').match(/[^a-z0-9 ]+/);

Here you go!

Coarse answered 29/3, 2012 at 14:22 Comment(0)
I
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/.

Imago answered 21/8, 2015 at 4:55 Comment(0)
E
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

Electricity answered 28/4, 2010 at 14:47 Comment(0)
J
2
$("input[name='option[colour]'] :checked ")
Janeyjangle answered 9/12, 2009 at 11:24 Comment(0)
E
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']")

Ethe answered 18/2, 2018 at 4:27 Comment(0)
D
1

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

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

Dawn answered 21/11, 2015 at 8:15 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.