0

Maybe someone can give me a hint...

I have the following code and experience a strange behaviour in javascript (node.js):

var a = "img{http://my.image.com/imgae.jpg} img{http://my.image.com/imgae.jpg}"
var html = a.replace(/img\{(.*)\}/g, '<img src="$1" class="image">');
//result: <img src="http://my.image.com/imgae.jpg"  class="image""> 

As you can see, the occurrence in the string (a markup thing) is replaced by an img tag with source as expected.

But now something strange. In the markup are probably several elements of type img{src}

var a = "img{http://my.image.com/imgae.jpg} some text between img{http://my.image.com/imgae.jpg}"
var html = a.replace(/img\{(.*)\}/g, '<img src="$1" class="image">');
//result: <img src="http://my.image.com/imgae.jpghttp://my.image.com/imgae.jpg"  class="image"">

The result is strange. in $1 all matches are stored and accumulated... And there is only one image tag.

I am confused...

hexacyanide
  • 88,222
  • 31
  • 159
  • 162
marschro
  • 791
  • 8
  • 23

3 Answers3

1

Use this to stop at the first closing curly bracket.

var html = a.replace(/img{([^}]*)}/g, '<img src="$1" class="image">');
Casimir et Hippolyte
  • 88,009
  • 5
  • 94
  • 125
1

Try: a.replace(/img\{(.*?)\}/g, '<img src="$1" class="image">');

I found out about adding ? makes regex non-greedy here

Community
  • 1
  • 1
bits
  • 8,110
  • 8
  • 46
  • 55
0

I think it's probably more important that you understand how this is working. .* can be a dangerous regular expression if you don't understand what it will do because it is greedy and will consume as much as it can, and some linters will warn against it.

So if you break down your regex you will find that the img\{ part matches the first part of the string (.*) matches http://my.image.com/imgae.jpg} some text between img{http://my.image.com/imgae.jpg and the final } matches the closing } because this is the largest string that matches the expression.

The best solution is to use ([^}]*), which matches anything except } because you know that anything between the image {} will will not be a closing brace.

You can test your regex to see what it is matching:

var reg = /img\{(.*)\}/g
var a = "img{http://my.image.com/imgae.jpg} img{http://my.image.com/imgae.jpg}"
var groups = a.match(reg)

// we can see what the first group matched
// groups[0] === "http://my.image.com/imgae.jpg} img{http://my.image.com/imgae.jpg"
Matt Esch
  • 22,661
  • 8
  • 53
  • 51