Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer
 
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 (Abbot) 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 (Abbot) 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 browsing the Monastery: (9)
As of 2015-03-04 04:55 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    When putting a smiley right before a closing parenthesis, do you:









    Results (96 votes), past polls