Reputation: 34503
Assume the following URL: http://a2.mzstatic.com/us/ryoyo0/078/Purple100x100/v4/38/e3/b4/38e3b4a2-b422-8d1e-69f2-593fc035c9d4/mzl.vqhwzhhc.100x100-75.jpg
We want to replace the last occurrence of 100x100 with 256x256. The URL should read:
http://a2.mzstatic.com/us/ryoyo0/078/Purple100x100/v4/38/e3/b4/38e3b4a2-b422-8d1e-69f2-593fc035c9d4/mzl.vqhwzhhc.256x256-75.jpg
Here's our JavaScript replace method:
replace( /100x100(?!100x100)/, '256x256' )
Unfortunately, we consistently replace the first, not the last, occurrence.
What are we doing wrong?
Thanks!
Upvotes: 1
Views: 253
Reputation: 58521
Yet another approach, due to possibly misunderstood intentions, which only replaces 100x100
s that appear in the filename part (with no /
appearing after it in the string) of the url.
replace(/100x100([^\/]*)$/, '256x256$1')
Works by...
100x100
([^\/]*)
$
256x256
and the first capture group, $1
If there is no match after the last /
in the string, then no replacements are done.
N.B. I checked the speed of this answer, my other answer, and the answer of @Daedalus, and whilst I would normally expect avoiding assertions to speed up the regex, in this case, I have found them to be all identical in speed, and be very fast, running a couple of hundred thousand times a second on my computer.
Upvotes: 0
Reputation: 58521
Another way to do it...
replace( /(.*)100x100/, '$1256x256' )
Works by...
100x100
as greedily as possible, with (.*)
, into group 1100x100
$1
and then adding 256x256
in place of the non-captured matchN.B. This method can only work for the last match (or first if you make the initial capture un-greedy by adding a ?
after the .*
)
It is usually good to avoid using look-around assertions, for performance reasons, for compatibility with various regex implementations, and I believe also for readability.
var url = "http://a2.mzstatic.com/us/ryoyo0/078/Purple100x100/v4/38/e3/b4/38e3b4a2-b422-8d1e-69f2-593fc035c9d4/mzl.vqhwzhhc.100x100-75.jpg"
console.log(url.replace(/(.*)100x100/, '$1256x256'))
// OUTPUT:
// http://a2.mzstatic.com/us/ryoyo0/078/Purple100x100/v4/38/e3/b4/38e3b4a2-b422-8d1e-69f2-593fc035c9d4/mzl.vqhwzhhc.256x256-75.jpg
Upvotes: 3
Reputation: 1667
Try this: replace( /100x100(?!.*100x100)/, '256x256' )
Adding the .*
accounts for additional characters between the first occurrence and the last occurrence of 100x100
.
Note - While my answer describes what you did wrong in your pattern and how to fix it, the answer provided by Billy Moon is probably a better pattern for what you seem to be trying to do.
Upvotes: 4
Reputation: 3581
You could change your negative lookahead to look for the slash also. Since the second occurrence ends with a period, not a slash, that should solve it.
/100x100(?!\/)/
Upvotes: 0