Say I have string example_photo_name1.png and example_photo_name2.png. I want to remove everything after first . and everything before last _.
The expected output is name1 and name2.
I could remove everything after first . by using pattern (.*)\.[^\.]*$. However, I do not know how to remove everything before the last _.
How can I do this?
You could use pattern (?<=_)(?!.+_).+(?=\.)
Pattern explanation:
(?<=_) - positive lookbehind - assert what preceeds is underscore
(?!.+_) - negative lookahead - assert what follows does not contain any underscore (so we are sure we are just behind last underscore)
.+ - match one or more of any characters
(?=\.) - assert what follow is dot .
Matched text will be exactly what you want.
Something like this might work:
const string = 'example_photo_name1.png';
string.replace(/^.*_(.*?)\.[^.]*$/, '$1');
If you want the prefix xxx_ and the suffix .xxx to be optional then you can wrap them in non capturing groups and add the proper quantifier:
/^(?:.*_)?(.*?)(?:\.[^.]*)?$/
This way string like:
hello_world => world
world.jpg => world
The (.*)\.[^\.]*$ pattern of yours (used with .replace and $1) removes the last . and the rest of the string.
You can use
text = text.replace(/^.*_|\..*/g, '')
See the regex demo. Details:
^.*_ - start of a string, any zero or more chars other than line break chars as many as possible, and then a _ char| - or\..* - a dot and then any zero or more chars other than line break chars as many as possibleSee a JavaScript demo:
const texts = ['example_photo_name1.png', 'example_photo_name2.png'];
const re = /^.*_|\..*/g;
for (const text of texts) {
console.log(text, '=>', text.replace(re, ''))
}