Chad Brown
Chad Brown

Reputation: 1667

Regex Replace only working on Last Match

I'm trying to replace the src of a number of image html elements in plain text (before they are rendered in the browser).

Here's what I have so far

var base = './images';
        
var sample = '<p><img src="1.png" alt="image-1"></p><p><img src="2.png" alt="image-1"></p><p><img src="3.png" alt="image-1"></p>';
        
sample = sample.replace(/(<img.+src=")(?!http:\/\/)(.*?)"/g, '$1' + base + '/$2"');
        
$('pre').text(sample);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<pre></pre>

However it only replaces the src of the last image element. What am I missing here?

Upvotes: 2

Views: 46

Answers (2)

Johny Skovdal
Johny Skovdal

Reputation: 2104

As @elclanrs metions in a comment, it seems like you are using the wrong approach here. Changing it trough the DOM via jQuery or the like seems a more appropriate method.

That being said, if, for some reason, this is the opportune way to solve it (I do not know all the variables), you should solve it by making the RegEx more explicit. Greedy matching generally performs the best, and having to use lazy evaluation (non-greedy) is generally a sign that either your RegEx is not specific enough, or that you are using RegEx to solve something that should not be solved with RegEx. This should do the trick somewhat:

var base = './images';
        
var sample = '<p><img src="1.png" alt="image-1"></p><p><img src="2.png" alt="image-1"></p><p><img alt="image-1" src="3.png"></p>';
        
sample = sample.replace(/(<img[^>]+src=")(?!http:\/\/)([^"]+)"/g, '$1' + base + '/$2"');
        
$('pre').text(sample);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<pre></pre>

Not exactly sure I'm doing the code tags correct though. Still learning to use those.

Upvotes: 1

Paul Roub
Paul Roub

Reputation: 36458

The greedy match in <img.+src is catching everything between the first img and the last src; your $1 is therefore

<img src="1.png" alt="image-1"></p><p><img src="2.png" alt="image-1"></p><p><img src="

Change to a non-greedy match:

sample = sample.replace(/(<img.+?src=")(?!http:\/\/)(.*?)"/g, '$1' + base + '/$2"');

var base = './images';
        
var sample = '<p><img src="1.png" alt="image-1"></p><p><img src="2.png" alt="image-1"></p><p><img src="3.png" alt="image-1"></p>';
        
sample = sample.replace(/(<img.+?src=")(?!http:\/\/)(.*?)"/g, '$1' + base + '/$2"');
        
$('pre').text(sample);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<pre></pre>

Upvotes: 3

Related Questions