Beefy Boxes and Bandwidth Generously Provided by pair Networks
Don't ask to ask, just ask
 
PerlMonks  

PCRE help with negative match

by Oolankaloophid (Initiate)
on Aug 11, 2013 at 00:21 UTC ( [id://1048960]=perlquestion: print w/replies, xml ) Need Help??

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

Trying to write a regex to NOT match line 1 but will match line 2 and 3. The string will not be anchored.

9759-222-sdfgh1-001-aaa-1234-abc

8898-222-sdfgh1-001-aaa-1234-abc

1234-222-sdfgh1-001-aaa-1234-abc

My regex is:

 (?<!9759-222)(\w\- {24})

Replies are listed 'Best First'.
Re: PCRE help with negative match
by toolic (Bishop) on Aug 11, 2013 at 00:28 UTC
    This works for your input data:
    use warnings; use strict; use YAPE::Regex::Explain; while (<DATA>) { print if /(?<!9759)-222-\w/; }

    Here's what your regex does: Tip #9 from the Basic debugging checklist: YAPE::Regex::Explain

    use warnings; use strict; use YAPE::Regex::Explain; my $re = '(?<!9759-222)(\w\- {24})'; my $parser = YAPE::Regex::Explain->new($re); print $parser->explain(); __END__ The regular expression: (?-imsx:(?<!9759-222)(\w\- {24})) matches as follows: NODE EXPLANATION ---------------------------------------------------------------------- (?-imsx: group, but do not capture (case-sensitive) (with ^ and $ matching normally) (with . not matching \n) (matching whitespace and # normally): ---------------------------------------------------------------------- (?<! look behind to see if there is not: ---------------------------------------------------------------------- 9759-222 '9759-222' ---------------------------------------------------------------------- ) end of look-behind ---------------------------------------------------------------------- ( group and capture to \1: ---------------------------------------------------------------------- \w word characters (a-z, A-Z, 0-9, _) ---------------------------------------------------------------------- \- '-' ---------------------------------------------------------------------- {24} ' ' (24 times) ---------------------------------------------------------------------- ) end of \1 ---------------------------------------------------------------------- ) end of grouping ----------------------------------------------------------------------
      Giving it a shot now, thanks
Re: PCRE help with negative match
by 2teez (Vicar) on Aug 11, 2013 at 00:28 UTC

    like this:

    for (qw( 9759-222-sdfgh1-001-aaa-1234-abc 8898-222-sdfgh1-001-aaa-1234-abc 1234-222-sdfgh1-001-aaa-1234-abc )){ print $_,$/ if!/^9/; }
    NOTE: That this would only work if there are no other string that start with '9' in your dataset.
    UPDATE:
    Please also see perlrequick and perlre.

    If you tell me, I'll forget.
    If you show me, I'll remember.
    if you involve me, I'll understand.
    --- Author unknown to me
      There will be hundreds, Thanks though.

        There will be hundreds, Thanks though.

        Then you have to specify more precisely what is the rule for matching a line and not the other. The !/^9/ regex given by 2teez meets perfectly the incomplete requirement you gave: it does not match the first line and does match the two others. An example is always vary useful for comprehension and illustration, but it is not a substitute for a functional rule explaining exactly what you need. May be changing 2teez's general code to something more specific such as !/^9759/ will do the trick, but it might now be too specific, how shall we know if you don't tell us? Please detail your requirement.

        Just a side question: you mention PCRE in the title of your post. Perl is certainly not using PCRE, since PCRE is basically a library to make Perl's internal regexes available functionalities similar to Perl's internal regexes available to languages other than Perl. Does that mean that you are using another language? I personally don't particularly care, but if such is the case, it means that we can offer you only pure regexes, not Perl code snippets.

        Update: Following an Anonymous Monk's comment just below, slightly modified my sentence above in order not to give the impression that PCRE is identical to Perl's internal regexes, it has quite similar functionalities, but it is clearly not the same thing.

Re: PCRE help with negative match
by sundialsvc4 (Abbot) on Aug 13, 2013 at 04:30 UTC

    Like many others, I do not see an immediately-obvious “bright-line rule” here that could easily be expressed in a regex.   And even if I did, I think that the resulting “solution” would be very, very difficult to maintain over time.

    Therefore, if it were me, I would simply split() the string by dashes, then follow this by a series of explicit conditional tests, such as the next unless statements in this snippet:

    while (<FILEHANDLE>) { my @pieces = split(',', $_); next unless ($pieces[0] eq '8898'); next unless ($pieces[2] eq 'sdfgh1'); ... # IF WE MAKE IT ALL THE WAY HERE IT'S A GOOD REC DO SOMETHING }

    It is, I think, “immediately obvious” what this code is doing, and it is also obvious how to extend it and/or change it without breaking it.   Whereas it is a very difficult thing indeed to have to deal with “clever, efficient” code that “seemed to work okay” at the time that it was written but now rightly shows itself to be a house of cards.   I fear that “regex cleverness” would be nothing but trouble in the long run here.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1048960]
Approved by toolic
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others studying the Monastery: (8)
As of 2024-03-28 11:58 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found