How to use a regular expression in querySelectorAll?
Asked Answered
S

4

76

On a page I'm doing I will be ending up with custom link elements like this:

<link rel="multiply" type="service/math" src="path/to/service">
<link rel="substract" type="service/math" src="path/to/service">
...

I'm trying to use querySelectorAll to retrieve all link elements with a type service/... specified and am getting nowhere.

Currently I'm selecting this:

root.querySelectorAll('link');

which gives me all <link> elements when I only want the ones with type service/.*

Questions:
Can I add a regex to a QSA selector? If so, how to do it?

Steepen answered 28/5, 2013 at 12:0 Comment(1)
M
143

You can't really use a regular expression in a selector but CSS selectors are powerful enough for your need with a "starts with" syntax inspired by regexes.

You can use a substring matching attribute selectors : link[type^=service]

Reads "Nodes of type link with an attribute type starting with "service"

From the formal specification:

[att^=val]

Represents an element with the att attribute whose value begins with the prefix "val". If "val" is the empty string then the selector does not represent anything.

Working JSFiddle

Maines answered 28/5, 2013 at 12:3 Comment(2)
@Steepen you're welcome! For what it's worth, a .filter call through the elements checking their type property is also a perfectly valid solution imho.Maines
this is useful for trying to gain access to a controller instance using the Controller-As syntax in Angular JS 1.5+. This is exactly the answer I needed when updating my angular app using the controller-as syntax and wanted to have console-level access to their scopes: angular.element( document.querySelectorAll( '[ng-controller^="' + <controller name> + '"' )[0] ).scopePounds
H
19

I know this is 7 years old, but this is how you do it (for attribute values):

function DOMRegex(regex) {
    let output = [];
    for (let i of document.querySelectorAll('*')) {
        if (regex.test(i.type)) { // or whatever attribute you want to search
            output.push(i);
        }
    }
    return output;
}
console.log(DOMRegex(/^service\//)); // your regex here
<link rel="multiply" type="service/math" src="path/to/service">
<link rel="substract" type="service/math" src="path/to/service">
<link rel="test" type="notservice/math" src="path/to/notservice">
<div id="some-other-node"></div>

To search all element attributes, you can use this:

function DOMRegex(regex) {
    let output = [];
    for (let i of document.querySelectorAll('*')) {
        for (let j of i.attributes) {
            if (regex.test(j.value)) {
                output.push({
                    'element': i,
                    'attribute name': j.name,
                    'attribute value': j.value
                });
            }
        }
    }
    return output;
}
console.log(DOMRegex(/(?<!t)service/)); // your regex here
<link rel="multiply" type="service/math" src="path/to/service">
<link rel="substract" type="service/math" src="path/to/service">
<link rel="test" type="notservice/math" src="path/to/notservice">
<div id="some-other-node"></div>

I put it in a nice object layout for you.

Hyaloplasm answered 2/6, 2020 at 3:51 Comment(2)
I liked this so much that I combined both functions into a single parameterized function - you can find a "gist" of that code hereDisembowel
You can use const instead of let in for..of loops. And needless to say, querying and iterating every element isn't going to be performant.Goddaughter
G
6

The post is quite old but it may be helpful for someone. If like clause is needed and we don't want to search by only the start, the following syntax can be used:

document.querySelectorAll('[type*=service]');
Gardas answered 17/8, 2022 at 6:52 Comment(0)
O
1

For your example below:

<link rel="multiply" type="service/math" src="path/to/service">
<link rel="substract" type="service/math" src="path/to/service">

You cannot use Regular Expression(Regex) but can use CSS Selector for querySelectorAll() as well as querySelector() as shown below. *You can see 6.2. Substring matching attribute selectors.

link[type^="service"] can select all <link>s whose type attribute starts from service:

document.querySelectorAll('link[type^="service"]');
// rel="multiply"'s <link> and rel="substract"'s <link>

[type^="service"] can also select all <link>s whose type attribute starts from service but I don't recommend it without link because it is less specific so it may also select other elements:

document.querySelectorAll('[type^="service"]');
// rel="multiply"'s <link> and rel="substract"'s <link>

link[type*="service"] can also select all <link>s whose type attribute contains service:

document.querySelectorAll('link[type*="service"]');
// rel="multiply"'s <link> and rel="substract"'s <link>

In addition, link[src&="service"] can also select all <link>s whose src attribute ends with service:

document.querySelectorAll('link[src&="service"]');
// rel="multiply"'s <link> and rel="substract"'s <link>
Ought answered 15/5, 2023 at 23:27 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.