tags:

views:

92

answers:

3

What is need is given the following string "Other Text [[MyText]] Some Other Text", and given some specific characters like "[[" for start and "]]" for end, to be able to match "[[MyText]]".

Given the following regex = "(\[\[)(.*)(\]\])" I am able to match what I want, but not exactly.

Lets say I have this string "Other Text[[ Something...[[MyText]]......something...[[MyOtherText]]" - I need to have 2 matches here "[[MyText]]" && "[[MyOtherText]]". My regex is too eager and matches more than I really want to.

Please, besides the answer I am looking to understand how it works, so a few comments as well will be helpful. Thanks.

+1  A: 

What you need is this :

regex = "\[\[([^\[]*)\]\]"

It will will blow up if you have a '[' in your text your trying to match, or nested pairs.

The reason it works this way is the default greedy matching of most regex implementations. In short greedy matching is taking as much as the match could possibly cover. The reason my regex works is that it does not allow another "[" (so it can't greedy match into the next set). Enjoy your wiki work.

C. Ross
Looks dubious to me - the catcher clause matches zero or more open square brackets (after the initial two). That wasn't in the question.
Jonathan Leffler
That regex will match "[[]]", "[[[[[[[[]]", etc. Not "[[MyText]]". You probably meant "\[\[[^\]]*\]\]"
Bart Kiers
Thanks Johnathan, Bart, I forgot the all important ^.
C. Ross
@C.Rohss :D - the caret as written in `\[\[(^\[*)\]\]` only matches itself. You might be thinking of a negated character class: `\[\[([^]]*)\]\]`, but that disallows '[[abc[def]ghi]]' which should be matched. The non-greedy regex ('`.*?`') is probably the best solution.
Jonathan Leffler
@Jonathan: Right (and sorry about the h), fixed the [^\[] issue. The non-greedy regex is probably a better solution in the long term, if nothing else but for readability. Is ? as a non-greedy symbol supported by most implementations?
C. Ross
+5  A: 

Maybe you're looking for non-greedy pattern or 'perlre'.

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

Note that additional '?' character;

Rubens Farias
+1, but how does it return both matches?
mouviciel
That worked. I should really stop using Visual Studio Find dialog to test my regex expressions, as I tried that, and Studio found nothing!
Ivan Zlatanov
try this one: http://www.radsoftware.com.au/regexdesigner/
Rubens Farias
@mouviciel: what was happening before was that a single regex was grabbing all the material from the first '[[' to the second ']]'. As fixed, the regex only grabs the material between the first '[[' and the first ']]', allowing a second pass starting after the ']]' to grab the second '[[...stuff...]]' phrase.
Jonathan Leffler
@Ivan: as far as Visual Studio goes, avoid it like the plague with regular expressions. The designers decided to use their own non-standard set of regexes. It's not even the flavor that the .NET runtime uses: http://www.codinghorror.com/blog/archives/000633.html
LoveMeSomeCode
A: 

Try:

\[{2}(?:(?!]]).)*]]

Also works with single ['s and ]'s inside your double [[ and ]]'s.

For a good explanation, see: http://www.regular-expressions.info/repeat.html

Note that ] is not a meta character (outside a character class), so there's no real need to escape it.

Bart Kiers