2

I wrote this regexp to capture the strings below.

\!\[(.*?)?\]

All the strings below should match and return an optional string that's inside the first set of square brackets.

![]
![caption]
![]()
![caption]()
![caption][]

The problem is that this string also matches and returns ][ because the regex thinks it's between the first [ and last ].

![][] // Should not match, but does and returns "]["

How do I fix this?

Jumbalaya Wanton
  • 1,601
  • 1
  • 25
  • 47
  • Are you sure about that regex matching `][`? Plus the last `?` is redundant. `*?` already takes into consideration 'no match'. – Jerry Jan 04 '14 at 11:22
  • I'm using scriptular.com and it shows me that in the results. Could scripular be broken? Here's a share link http://scriptular.com/#%5C!%5C%5B(.*%3F)%3F%5C%5D%7C%7C%7C%7C%7C%7C%7C%7C%5B%22!%5B%5D%22%2C%22!%5Bcaption%5D%22%2C%22!%5B%5D()%22%2C%22!%5Bcaption%5D()%22%2C%22!%5B%5D%5B%5D%22%2C%22!%5Bcaption%5D%5B%5D%22%2C%22%22%5D – Jumbalaya Wanton Jan 04 '14 at 11:24
  • Sorry about the long link, but that's what it generates. – Jumbalaya Wanton Jan 04 '14 at 11:24
  • Seems to me like it should *match*, it just shouldn't capture `][`. Debuggex seems to show it working the way you expect. – Chris Hayes Jan 04 '14 at 11:26
  • @JumbalayaWanton The syntax for a link is `[text](http://stackoverflow.com/)` – HamZa Jan 04 '14 at 19:49

3 Answers3

2

Just remove the ? outside (.*?), that is redundant.

var myArray = ["![abc]","![caption]", "![def]()", "![caption]()","![caption][]"];
myArray.forEach(function(current) {
    console.log(/!\[(.*?)\]/.exec(current)[1]);
});

Output

abc
caption
def
caption
caption

Check how the RegEx works here

thefourtheye
  • 233,700
  • 52
  • 457
  • 497
  • Thank you. I thought the `?` was needed because the caption was option. I'm not sure if I should ask another question, but I want the regex to not match if thee second set of have something in them. So `![](something in here will stop the match)` or `![][something in here will also stop the match]`. – Jumbalaya Wanton Jan 04 '14 at 11:28
  • +1. Also, I just noticed that `\!\[(.*?)?\]` works as intended on PCRE but not on JS' engine. Hmmm. – Jerry Jan 04 '14 at 11:32
  • 1
    @thefourtheye No, I mean, in PCRE, `\!\[(.*?)?\]` matches `![]` (intended) but in JS, it matches `![][]`. – Jerry Jan 04 '14 at 11:40
1

Use this regex:

\!\[([^\]]*)\]

It means that it expects a "last" ] but makes internal ones invalid. This should solve your issue.

d'alar'cop
  • 2,357
  • 1
  • 14
  • 18
1

My preference is this if you want to ignore catching the things like this ![[]]

\!\[([^\[\]]*)\]
Sabuj Hassan
  • 38,281
  • 14
  • 75
  • 85