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
Related
I am trying to do some html scraping with JavaScript, and would like to take the a href link and replace it into a hyperlink on a Discord embed. I am having trouble with regex, I am finding it very difficult to learn.
I assume I will also need another regex to capture it all so I can replace it with my desired target?
This is an example raw html that I have:
An **example**, also known as a example type
to make this readable within a Discord embed, I am looking for a desired output of:
An **example**, also known as a [**example type**](https://www.example.com/example%20type)
I have tried extracting the URL via regex, which I can match however, I am having issues with extracting the link and the (I think its called target? The 'example type' in the example link text) and then replacing the string with my desired output.
I have the following: (https://regexr.com/73574)
/href="[^"]+/g
This matches href="https://www.example.com/example%20type, and feels like a very early step, it includes 'href' in the match, and it does not capture the target.
EDIT:
I apologise, I did not think about additional checks, what if the string has multiple links? and text after them, for example:
An **example**, also known as a example type is the first example, and now I have second example
with a desired output of:
An **example**, also known as a [**example type**](https://www.example.com/example%20type) is the first example, and now I have [**second**](https://www.example.com/second) example
Try this: (?<=href=")[^"]*
By using a lookbehind, you can now verify that the text behind is equal to href=" without capturing it
Demo: https://regex101.com/r/2qMnPt/1
You can use regular expression groups to capture things that interest you. My regular expression here might be far from perfect but I don't think that's important here - it shows you a way and you can always improve it if needed.
Things you have to do:
prepare regex that captures groups that you need (anchor tag, anchor text, anchor url),
remove the anchor tag completely from the text
inject anchor text and anchor href into the final string
Here's a quick code example of that:
const anchorRegex = /(<a\shref="([^"]+)">(.+?)<\/a>)/i;
const textToBeParsed = `An **example**, also known as a example type`;
const parseText = (text) => {
const matches = anchorRegex.exec(textToBeParsed);
if (!matches) {
console.warn("Something went wrong...");
return;
}
const [, fullAnchorTag, anchorUrl, anchorText] = matches;
const textWithoutAnchorTag = text.replace(fullAnchorTag, '');
return `${textWithoutAnchorTag}[**${anchorText}**](${anchorUrl})`;
};
console.log(parseText(textToBeParsed));
Solution:
const input = 'An **example**, also known as a example type first and second here no u and then done noice';
const output = input.replace(/<a href="([^"]+)">([^<]+)<\/a>/g, '[**$2**]($1)')
console.log(output);
Regex breakdown:
<a href=" - Matches the opening <a href" HTML tag
([^"]+) - This is a capturing group, matches a number of characters that are not double quotes
"> - Matches the closing double quotes, including the closing tag '>'
([^<]+) - Another capturing group, matches a number of characters that are not a less than symbol
<\/a> - Matches the closing HTML tag
I then use the replace method seen in my output variable.
Within the replace, you see two options (regex, replaceWith)
The first option is obvious, its the regex. The second option [**$2**]($1), uses the capturing groups we see in the regex, the first group $1 provides the link within the HTML tag, and $2 provides the HTML target (the name after the link, for example in my input variable, the first target you see is: 'example type'.
The only important bits in this option is: $2 and $1, however I wanted to display them in a certain way, [**target**](link).
i want to replace all the src attribute inside a string of HTML adding a '?a' at the end of the url to fix a caching issue that i'm having.
So far i got this:
str.replace(/src=".*?"/gi, "src");
But i have no idea how to do the 2nd parameter to get what is matched and add the '?a' at the end.
Example:
<img src="mysite.com/logo.png" /> should become
<img src="mysite.com/logo.png?a" />
Thank you in advance, Daniel!
The first problem is that you are matching the entire src attribute instead of what's within the src attribute.
The second problem is that you aren't putting the match into your replacement.
This would be the correct regex:
str.replace(/src="(.*?)"/gi, 'src="$1?a"')/;
Adding brackets around the match .*? makes sure you match just that part instead of the whole regex, adding $1 into the second parameter makes sure you put the match back into the replacement.
You also have to re-enter src="" into the replacement, because the whole regex match will be replaced.
You can use this /src="(.*?)"/gi regex to find and replace the content.
I have a dynamic URL, which i want to append some string at last
'http://staging.mydomain.name.com/test/7bb12c5f7b2f4f008261bea2d3f5abd2/200x200.png'
want to append "preview" before size (200x200.png which is also dynamic), something like below
'http://staging.mydomain.name.com/test/7bb12c5f7b2f4f008261bea2d3f5abd2/preview/200x200.png'
I have seen Javascript match to remove part of file name from URL - replace the last occurence but its not what i want.
Thanks
Just use a simple regular expression like:
'http://.../200x200.png'.replace(/[^\/]+$/, 'preview/$&')
You can do like str.replace(/(/\d+x\d+.)/,'/preview$1')
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.
I am trying to get just a part of a string with a regex
this is the string i am testing
class1 container _box _box_CEC493
the string is a series of classes applied to an element.
what i would like to get is just CEC493 which changes since the regex will be applied to a bunch of different elements (therefore string like the one above)
the regex i am using now is
/\s_box_([0-9a-zA-Z]+)/
which returns
_box_CEC493, CEC493
How can i modify it in order to get just the second value (CEC493)?
Thank you
You could probably just split the string:
var str = "class1 container _box _box_CEC493";
var match = str.split('_').pop();
alert(match);
DEMO
The standard way regexes come back is like this:
[0]: Whole result
[1]: First parentheses capture group
etc
So the standard way that people access these is with result[1]. Does that cause any issues in your case?
[updated]
instead of selecting all characters, select until an unwanted character,, and since you are selecting from a number of classes, it is possible that you have the _box_.. class alone without a space before it, so don't use space at the beginning of your regex selector.
str.match(/_box_([^\s]*)/)[1]
jsfiddle