I would like to find all usages of a certain html tag and filter the results via attributes.
<tag attribute1="'text123'" />
<tag attribute2="'true'"
attribute1="'text1'"/>
<tag attribute2="'true'"/>
=> Find all tags "tag" with attribute1 set => 3rd example is ignored
Searching could be an alternative, but should respect multilines.
Any help would be appreciated
We could have a quick go with this simple pattern:
<tag\b[^>]*?attribute1\s*=\s*"([^"]*)"[^>]*>
But it's not 100% correct.
<tag\b
will search for the opening tag, with \b
as word
boundary, to avoid matching "<tagada />", or something
starting with "tag". We can improve it by replacing it by
<\s*tag\b
as it is allowed to have space chars before the tag
name.
[^>]*?
will match any chars not being ">", in an un-greedy way,
because we want the search engine to try matching attribute1
after the optional preceding attributes.
attribute1\s*=\s*"([^"]*)"
will find attribute1 with its
value, captured in the group n°1. We could be more precise by
adding \b
in front of attribute1
just to be sure not to match
another attribute which could be called myattribute1. But
unfortunately, this will not totally work, because HTML attributes
can contain hyphens, such as the common data-* attributes, so
in our case, we could have my-attribute1="...", which would not
work by using the preceding \b
. But this can be solved by
using a positive lookbehind, searching for a space char before it,
leading to (?<=\s)attribute1\s*=\s*"([^"]*)"
.
The last part [^>]*>
is optional, as it matches the attributes
after attribute1 and the closing ">". We don't really need it,
but this depends on what you would like to do with your search
results.
Adding the improvements, we get this pattern:
<\s*tag\b[^>]*?(?<=\s)attribute1\s*=\s*"([^"]*)"[^>]*>
According to IntelliJ IDEA's documentation, the search engine uses Java's regular expression flavour, so it should also work with this search pattern.
Test it live with Java's regex flavour: https://regex101.com/r/spZG7c/2
const pattern = /<\s*tag\b[^>]*?(?<=\s)attribute1\s*=\s*"([^"]*)"[^>]*>/giu;
// When the document is ready, attach the event handlers.
document.addEventListener("DOMContentLoaded", function () {
const input = document.getElementById("input");
const searchButton = document.getElementById("search");
searchButton.addEventListener('click', (event) => {
console.log([...input.value.matchAll(pattern)]);
event.preventDefault();
return false;
});
});
*, *::before, *::after { box-sizing: border-box; }
form {
/* Display the form in two columns. */
display: flex;
flex-direction: row;
column-gap: 1em;
}
form > div:first-child {
width: calc(100% - 6em); /* 100% - gap - right column. */
min-width: 20em; /* Enough for the textarea content. */
}
form > div:last-child {
width: 5em; /* Enough for the button. */
}
textarea {
width: 100%; /* Override cols="80". */
font-size: .85em;
}
.as-console-row-code {
font-size: .85em !important; /* Instead of 13px. */
}
<form action="#">
<div>
<textarea name="input" id="input" cols="80" rows="13"
placeholder="Enter your HTML here"><tag attribute1="'text123'" />
<TAG attribute2="'true'" attribute1="'text1'"/>
<tag attribute2="'true'"/>
< tag type="apple" title="Golden apple"
ATTRIBUTE1="value" />
<tagger attribute1="something">
<tag data-id="6735"
attribute1="'some more text'"
required >
Whatever in here
</tag>
</tagger>
<tag matching="false" data-attribute1="" /></textarea>
</div>
<div>
<button id="search"
title="Search for <tag ... attribute1 ...>">
Search
</button>
</div>
</form>