Finding a DOM element by attribute name and value using regex - javascript

I am trying to find an anchor dom element which has attribute for example, href='/post/3534' by using document.querySelector and regex.
So something like,
document.querySelector("a[href='/post/(/[0-9]+/g)']")
but it obviously does not work.
What is the correct syntax for my purpose ?
I'd appreciate your help.

Selectors don't accept regular expressions - the best you'll be able to do is querySelectorAll the <a>s, and then .find the one whose href matches your condition:
const foundA = Array.prototype.find.call(
document.querySelectorAll('a[href^="/post/"]'),
a => /^\/post\/[0-9]+/.test(a.getAttribute('href'))
);
if (foundA) {
console.log(foundA.getAttribute('href'));
}
foobar
words
numbers

Related

How to replace last href occurrence in a string?

The text is something like the following
Stuff
More stuff
more
last thing
more
I need to replace what's inside the last href ocurrence in the text, with another reference as http://realreference.com/real?the one to replace
I can actually change the href of all ocurrences in the string with the global flag g after the regex /href="(.*?)"/ and a function like the following:
string.replace(/href="(.*?)"/g, () => {
return `href="http://realreference.com/real?the one to replace"`;
})
I would need to only change it in the last href ocurrence of the string, which in this case it's href="http://example.com/more?lasthing goes here"
If you are looking for a pure regex solution, you can use the following to find the last match:
pattern(?![\s\S]*pattern)
Example: href="(.+?)"(?![\s\S]*href="(.+?)")
See it yourself: regex101.com
Find all href with match and replace only last
You can use querySelector in order to query the desired element in the DOM. Using :last-of-type will make it select the last element of the type you select. Therefore, with this code in the first line, you will get the last <a>. After you get the element, you can replace its href attribute by using setAttribute.
let last_a = document.querySelector('a:last-of-type');
last_a.setAttribute('href', 'http://realreference.com/real?the one to replace');
console.log(last_a);
Stuff
More stuff
more
last thing
more

HTML IDs that start with a number

I generate GUIDs for id's in my HTML like
<div id="9121c01e-888c-4250-922f-cf20bcc7d63f">...</div>
According to HTML5 specs, this is valid. However, if you try to find such a element with document.querySelector or document.querySelectorAll, you'll get an error saying that the selector is invalid.
I know that for CSS rules, such an ID is not valid. Does the querySelector methods of 'document' rely on CSS?
Does the querySelector methods of 'document' rely on CSS?
The strings you pass querySelector and querySelectorAll are CSS selectors. So yes, they follow the rules of CSS selectors, one of which (as you mentioned) is that an ID selector cannot start with an unescaped digit. So they don't rely on CSS per se, but they follow the syntax of CSS selectors.
You can select that element either by escaping the first digit (which is fairly ugly*):
var e = document.querySelector("#\\39 121c01e-888c-4250-922f-cf20bcc7d63f");
...or by using an attribute selector:
var e = document.querySelector("[id='121c01e-888c-4250-922f-cf20bcc7d63f']");
Example:
document.querySelector("#\\39 121c01e-888c-4250-922f-cf20bcc7d63f").innerHTML = "Yes!";
document.querySelector("[id='9121c01e-888c-4250-922f-cf20bcc7d63f']").style.color = "green";
<div id="9121c01e-888c-4250-922f-cf20bcc7d63f">...</div>
Of course, if you're just getting the element by its ID and not using a compound selector starting with an ID, just use getElementById, which doesn't use a CSS selector, just the ID value as plain text:
var e = document.getElementById("9121c01e-888c-4250-922f-cf20bcc7d63f");
You only need the other form if you're using a compound selector ("#\\39 121c01e-888c-4250-922f-cf20bcc7d63f > span a"), or passing a selector string into something you don't have control over that you know will use querySelector.
* In a CSS selector, \ followed by up to six hex characters (plus a space if you don't use all six) specifies a character code in hex. 0x39 is the character code for the digit 9. And of course, we had to escape the \ in the string literal since otherwise it would have been consumed by the string literal.
Yes, they use CSS selectors
https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector
Syntax
element = document.querySelector(selectors);
where
element is an Element object.
selectors is a string containing one or more CSS selectors separated by commas.
But as you append the GUID as ids you can use document.getElementById();
It supports this case.

Regex, getElementsByTagName and getElementsByClassName

I call findElements when window.onLoad, with HTML code,
tmp2 selects all tags but the others don't. I really cannot figure out; thanks in advance.
function findElements(){
var tmp = document.getElementsByClassName("*"); // nothing
var tmp2 = document.getElementsByTagName("*"); // all tags, so regexp could be input arg.
var tmp3 = document.getElementsByTagName("b..."); // nothing, but body tag is supposed to be selected
}
The getElementsByTagName method does not accept regular expressions as arguments.
It accepts only strings which must either be:
The wild card *
An exact match for the element type
The getElementsByClassName method does not accept regular expressions.
It accepts only strings which must be:
An exact match for the class name
The querySelectorAll method can use attribute selectors to make more complex matching of attributes (including the class attribute), but even it does not support regular expressions.
If you really want to do a regular expression match, the you would need to select all elements with the wild card (getElementsByTagName("*")) and then loop over the results, testing each one in turn.

javascript regex for matching attributes in HTML string

Can anyone look at my regex in javascript and suggest a correct one?
I'm trying to select attributes(name/value) pairs in an HTML/XML string like following?
<unknowncustom:tag attrib1="XX' XX'" attrib2='YY" YY"' attrib3=ZZ""'>/unknowncustom:tag>
SOME TEXT that is not part of any tag and should not be selected, name='XX', y='ee';
<custom:tag attrib1="XX' XX'" attrib2='YY" YY"' attrib3=ZZ""'>/custom:tag>
I found many solutions but none seem foolproof (including this one Regular expression for extracting tag attributes)
My current regex selects the first attribute pair but can't figure out how to make it select all matching attributes. Here is the regex:
/<\w*:?\w*\s+(?:((\w*)\s*=\s*((?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))))[^>]*>/gim
Thanks
Let's have a go:
/(\w+)\s*=\s*((["'])(.*?)\3|([^>\s]*)(?=\s|\/>))(?=[^<]*>)/g
Regex is not ideal for this. If your attributes contain unescaped angle brackets < > it probably will not work.
Proof: http://regex101.com/r/dD4uT4

grab value of custom attribute

Is it possible to grab custom attribute like this 'something-20'
say for example it is in <div class="somecustomClass something-20"></div>
I want to grad the 19 so that I can manipulate it, because the css has block from something-1 to something-100
I used below code to retrieve tab id :
tabId = $('li').find('a').attr('href').replace('#tab', '');
is it the same approach?
That's not a custom attribute, it's a class. You'd have to get the entire class string, then probably use a regular expression to find the value you want.
It would be easier to use data- attributes:
<div class="somecustomClass" data-something="20"></div>
JS:
var value = $('.somecustomClass').data('something'); // 20
If you want it to be a custom attribute I suggest you do what Jason said in his answer. But if you want to grab the something-# elements and do something with them you can do the following.
for(var i=1;i<=100;i++) {
var el = $('.something-'+i);
//do something with the element to manipulate it
}
Similar. What the tab id thing does is 3 things
Part 1 is selecting the right element.
Part 2 is getting the value of the attribute that contains the data we want
Part 3 is getting the specific bit of the data that we want with a regular expression
For part 1, I'm not sure what you're using to identify these blocks in order to select them.
You could have $('[class^="something"]') to get all the elements that have a class that starts with the text 'something', but that will be quite slow. If you can use something like $('.somecustomClass') it will perform better.
If you just wanted to adapt the first matching element you came across, you could do this:
var myNumber = $('.somecustomClass')[0].className.replace(/.*?\bsomething\-(\d+).*/gi, "$1");
Apologies if you are already familiar with regular expressions, but for other readers this is a breakdown of what it does:
.*? means non-greedily select zero or more characters, \b means word boundary, then it finds the text 'something-' followed by one or more digits. Putting brackets around it captures what it finds there. Just in case you have classes after than, it has .* to get zero or more characters to find them too. /gi on the end of that means look globally through the class and i means be case-insensitive. $1 as the second argument of the replace function is the captured digits.

Categories