Beefy Boxes and Bandwidth Generously Provided by pair Networks
"be consistent"
 
PerlMonks  

Regex Modification

by Anonymous Monk
on Apr 10, 2013 at 06:43 UTC ( #1027898=perlquestion: print w/ replies, xml ) Need Help??
Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Hi..

I use the below given regex to match numbers in these forms

Should Match : 1. 123-456-789 2. 123.789.456 3. 963 456 741 Should Not Match : 1. 123-456.789 2. 123 789-456 3. 963.456 741 Regex: (?<!\d)\d{3}[\d$diff]{3,10}\d{3}(?!\d)) $diff contains : -.

But the regex matches both SHOULD MATCH and SHOULD NOT MATCH .How can I make it match only SHOULD MATCH?

Comment on Regex Modification
Download Code
Re: Regex Modification
by Athanasius (Prior) on Apr 10, 2013 at 06:57 UTC

    Use \1 to match the same delimiter:

    #! perl my @should_match = ( '123-456-789', '123.789.456', '963 456 741', ); my @should_not_match = ( '123-456.789', '123 789-456', '963.456 741', ); my $re = qr/\d{3}([ .-])\d{3}\1\d{3}/; for (@should_match) { if ($_ =~ $re) { print "ok\n"; } else { print "failed\n"; } } for (@should_not_match) { if ($_ =~ $re) { print "failed\n"; } else { print "ok\n"; } }

    Output:

    16:53 >perl 603_SoPW.pl ok ok ok ok ok ok 16:55 >

    Hope that helps,

    Athanasius <°(((><contra mundum Iustus alius egestas vitae, eros Piratica,

      This regex results in consecutive number not being matched like:

      Not Matched : 1. 123456789 2.123456789147

      Pls tell?

        How about
        use strict; use warnings; my @nums =( '123-456-789', '123.789.456', '963 456 741', '123-456.789', '123 789-456', '963.456 741', '123456789', '123-456' ); for my $num (@nums) { print "$num "; $num =~ s/[0-9]//g; if ($num =~ m/^([-. ])\1*$|^$/) { print "matches \n"; } else { print "does not match \n"; } }
        If the last number should not match, just delete the * in the regex
        This regex results in consecutive number not being matched like:
        Not Matched : 1. 123456789 2.123456789147
        Pls tell?

        That's because with this regex, a match requires separator characters from the set  [- .] to be present between each three-digit group; this requirement is implied by the specification-by-example in the OP. If you want something like '123456789' to match, try:

        >perl -wMstrict -le "my @numbers = ( '123-456-789', '123.456.789', '123 456 789', '123456789', '999-999.999', '999 999-999', '999.999 999', '9999-999-9999', '99-999-99', '0123456789', '999999-999', '999.999999', ); ;; my $diff = qr{ [-. ] }xms; for my $n (@numbers) { my $match = $n =~ m{ (?<! \d) \d{3} ($diff?) \d{3} \1 \d{3} (?! \d) }xms; print $match ? ' ' : 'NO', qq{ match: '$n'}; } " match: '123-456-789' match: '123.456.789' match: '123 456 789' match: '123456789' NO match: '999-999.999' NO match: '999 999-999' NO match: '999.999 999' NO match: '9999-999-9999' NO match: '99-999-99' NO match: '0123456789' NO match: '999999-999' NO match: '999.999999'

        I'm puzzled by the presence of '123456789147', which you seem to want to match. This is not in accord with the negative look-around assertions in your OP. Can you please clarify: do you want any sequence of nine or more digits to match? If so, where should the separator characters '- .' fall in relation to the digits?

Re: Regex Modification
by AnomalousMonk (Monsignor) on Apr 10, 2013 at 07:53 UTC

    I like the approach of Athanasius, although I would throw in a couple of negative look-around assertions (as in the code of the OP) to eliminate a match against something like '9999-999-9999'.

    $diff contains : -.

    This statement in the OP is ambiguous and potentially a serious bug. If the assignment to  $diff were indeed
        my $diff = ' -.';
    (one possible interpretation of the quoted statement), the '-' (hyphen) character would be treated as a range metacharacter in the  [\d$diff] (or  [\d -.] after interpolation) character class and the class would end up including all characters from ' ' (space, or \x20) through '.' (period) inclusive, i.e., [\d !"#$%&'()*+,-.] in the ultimate class, probably not what was intended.

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others lurking in the Monastery: (14)
As of 2014-07-11 12:53 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    When choosing user names for websites, I prefer to use:








    Results (224 votes), past polls