Birrel Birrel - 1 month ago 3x
Javascript Question

JavaScript, Regex - `.replace` is only removing the last-matched part (when multiple matches)

I am modifying a music player to not show anything in a song's title after a dash, or opening parentheses.

Expected Results:

Bennie And The Jets - Remastered 2014

// Becomes

Bennie And The Jets


The 59th Street Bridge Song (Feelin' Groovy)

// Becomes

The 59th Street Bridge Song


December, 1963 (Oh What A Night!) - 2007 Remastered Version

// Becomes

December, 1963


Ave Verum

// Becomes (remains...)

Ave Verum

The code I am using to make the modifications:

var song = 'some song name';

var title = function() {
var str = song;

var re = /(.*)(\s+((-|\()[^-\(]*))/g;

str = str.replace(re, '$1');

return str;

Which returns:

Bennie And The Jets


The 59th Street Bridge Song


December, 1963 (Oh What A Night!)


Ave Verum

The third case - where there is both a hyphen or a parentheses - falls short.

How can I force it to take the furthest-forward match (and, thus, everything following)?

Additionally (Edit #1)

The player does not insert spaces before the hyphen in hyphenated songs, and so the condition preceding the hyphen is

\s+ //One or more

Final Solution and Use (Edit #2)


Courtesy of Andy Ray, the final regex is:

var re2 = /\s*[(-].*$/;

(Use - For anyone with the same distaste for trailing song modifiers)

The offending music player is Spotify Player (for Mac, but this should work identically the same for other platforms). You can make changes like this 'cause the app is written as a Chrome Embedded Framework (CEF).

CEF is basically a website - HTML, CSS and (most importantly) JavaScript. Because if this, you can play around a bit, try things out, customize the things they won't normally let you customize.


The following process and code will NOT change your song titles anywhere else except for within the app, on the device you make the changes. All your account details are pulled from servers every time you open it.

On a Mac, the files of interest will be found in:


Where you will find a bunch of files with the extension
. These aren't actually files, but rather zipped directories containing the pertinent stuffs.

I unzipped them using The Unarchiver

// In terminal
cd /Applications/
find ./ -name \*.spa -exec unar {} \; // Or just the couple you need
find ./ -name \*.spa -exec rm {} \; // Be careful!

The Spotify app will run exactly the same, whether you have the zipped or unzipped directories.

To modify the song titles (specifically in the "Songs" and "Playlist" views), you'll want to look in:


Inside of both files, there is *only one reference to
. A quick find will get you to where you need to be. These lines are your offenders.

In both files, change the line:



name: function() {
var re1 = new RegExp('^' + '\\(.*\\).*', 'i')
var re1_2 = /(\((.*)\))/
var re2 = /\s*[(-].*$/g;

var str =;

if(re1.test(str)) {
str = str.replace(re1_2, '$2');

str = str.replace(re2, '$1');

return str;

And that's it, all done.

You start out with

Spotify Before

And come out with

Spotify After


The question I was asking about above only dealt with:

var re2 = /\s*[(-].*$/g;

The reason for the two preceding regex expressions (
) are because some songs (few!) have leading brackets:

(Everything I Do) I Do It For You

The two expressions, along with

if(re1.test(str)) {
str = str.replace(re1_2, '$2');

Makes it look like

Everything I Do I Do It For You

If that isn't a concern, you can just take those lines out.

This little hack might not be pretty in code, but sure is nice to look at in the app.


I think there are much simpler solutions to your problem.

Why not just replace anything at the end of the string, starting from a dash or an open paren, with nothing?

str.replace( /\s*[(-].*$/, '' );


\s* Any whitespace found before a paren or a -
[(-] either of the two characters "(" or "-"
.*$ everything else up to the end of the string

Additionally you could do this with a simple .substr() and .indexOf check for those characters.