73

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?

Super Kai - Kazuya Ito
  • 22,221
  • 10
  • 124
  • 129
frequent
  • 27,643
  • 59
  • 181
  • 333

4 Answers4

140

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

Community
  • 1
  • 1
Benjamin Gruenbaum
  • 270,886
  • 87
  • 504
  • 504
  • @frequent 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. – Benjamin Gruenbaum May 28 '13 at 12:11
  • 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^="' + + '"' )[0] ).scope` – jusopi Feb 25 '15 at 03:51
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.

SUM1
  • 771
  • 8
  • 13
  • 2
    I liked this so much that I combined both functions into a single parameterized function - [you can find a "gist" of that code here](https://gist.github.com/oze4/990e0846b0b535785b3f34c5df89be5e) – Matt Oestreich Jul 15 '20 at 05:44
5

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]');
AhmerMH
  • 638
  • 7
  • 18
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>
Super Kai - Kazuya Ito
  • 22,221
  • 10
  • 124
  • 129