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

I have a problem with a regular expression - I need to match and capture a regular expression which may or may not be surrounded by brackets, but do not want to capture the surrounding brackets. The code which I have is like this - Note that the regular expression has been simplified to /ab/ in this example:

my ($match) = $string =~ /<(ab)>/; ($match) = $string =~ /(ab)/ unless defined $match;

This feels however as if it could be simplified into a single regular expression.

Replies are listed 'Best First'.
Re: Help with Regular Expression matching
by Tomte (Priest) on Feb 18, 2004 at 11:03 UTC

    May be a little bit of an overkill, but does what you say you want ;-)

    my $reg1 = qr{((?:(?<=<)ab(?=>))|(?:(?<!<)ab(?!>)))}; while(<DATA>) { chomp; print $_, "\t", m/$reg1/?"yes $1":"no", "\n"; } __DATA__ <ab ab> <> <ab> ab __END__ Output: <ab no ab> no <> no <ab> yes ab ab yes ab

    regards,
    tomte


    Hlade's Law:

    If you have a difficult task, give it to a lazy person --
    they will find an easier way to do it.

Re: Help with Regular Expression matching
by Skeeve (Parson) on Feb 18, 2004 at 12:05 UTC
    Did you notice that /(ab)/ did also match <ab?

    So what you want us to create for you is something that your little example doesn't ddo.

    I'd suggest that you give us more information like:
    1. do you have some anchors?
      eg: /^(ab)$/ is more specific than /(ab)/
    2. is there anything in the original re that you simplified to ab that might help?
Re: Help with Regular Expression matching
by skx (Parson) on Feb 18, 2004 at 10:15 UTC

    So you want to match some text which might be surrounded by brackets?

    Just match against "<?" and ">?" for the bracket zero or more times.

    ($match) = $string =~ /<?(ab)>?/;
    Steve
    ---
    steve.org.uk
      This is a good suggestion, but I need to match /ab/ only when it surrounded or not surrounded by brackets, not where there is a bracket on only one side (as the <? and >? approach would allow).
Re: Help with Regular Expression matching
by ysth (Canon) on Feb 18, 2004 at 18:44 UTC
    my ($match) = grep defined, $string =~ /<(ab)>|(ab)/;
    or use (?(condition)...), taken almost literally from perlre:
    my ($quoted,$match) = $string =~ /(<)?(ab)(?(1)>)/x; # or: my $match = ($string =~ /(<)?(ab)(?(1)>)/)[1];