shockme has asked for the wisdom of the Perl Monks concerning the following question:

I'm stumped (big surprise). I have a string like the following:
[You want this code]. But under no circumstances do you \[want this c +ode]\.
I need a regex that will give me You want this code but not want this code (contained within the second set of brackets).

All I've been able to come up with is something that will break out on plain brackets. I need to be able to tell the regex engine to break on brackets but not on \brackets\.

(It is safe to assume that brackets and \brackets\ will always occur in pairs, however, brackets may occur within \brackets\.)

Any thoughts?

If things get any worse, I'll have to ask you to stop helping me.

Edit kudra, 2002-05-27 Corrected title

Replies are listed 'Best First'.
(elbie): regex for but not \\
by elbie (Curate) on May 27, 2002 at 01:00 UTC

    Look ahead and look behind assertions are perfect for this sort of thing. In this case, negative assertions can make sure that the extra pattern you specify (i.e. the backslash) doesn't occur:

    m/(?<!\\)\[.*?\](?!\\)/g should do what you want.

    Update: jeffa pointed out my .?* should in fact be a .*?

    elbieelbieelbie

Re: regex for but not \\
by graff (Chancellor) on May 27, 2002 at 00:58 UTC
    Just do it with two regex steps instead of one:
    s/\\\[.*?\]\\//g; # get rid of what you don't want first @wanted = (/\[(.*?)\]/g); # then get what you want
•Re: regex for but not \\
by merlyn (Sage) on May 27, 2002 at 13:59 UTC
    You could do it with a simple tokenization, altering only what you want. Presuming you want unescaped brackets to be magic, but backslash to escape both brackets and itself, you could tokenize as follows:
    my @tokens = / \\. # any backslashed character | \[ .*? \] # bracketed string (the one with magical powers) | [^\\\[\]]+ # any sequence of non-specials | . # catch-all (to inchworm past broken constructs like mismatched +brackets or backslash at end of string) /xgs; for (@tokens) { if (/^[(.*)\]$/s) { # it's special $_ = process($1); # replace with its expansion } elsif (/^\\(.)/s) { # it's escaped $_ = $1; } } my $result = join "", @tokens; # if that's what you want

    -- Randal L. Schwartz, Perl hacker