Beefy Boxes and Bandwidth Generously Provided by pair Networks
No such thing as a small change
 
PerlMonks  

Regex for matching dotted numbers

by techman2006 (Beadle)
on Jul 21, 2014 at 10:29 UTC ( [id://1094450]=perlquestion: print w/replies, xml ) Need Help??

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

Basically these are version number for a product. So the series can be as given below

  • 8.1.1
  • 8.100.1
  • 9.0.300.1
  • 9.0.301.1
  • 9.0.400.1
  • 9.0.401.1
  • 9.1.0.0
  • 9.100.1.0

So I need to make sure that if the version matches above then I need to skip running a particular script else run it.

The restriction for the pattern is given below

  • It should begin with either 8 or 9 or later.
  • It will contain 4 dots in the form of a.b.c.d

Replies are listed 'Best First'.
Re: Regex for matching dotted numbers
by AppleFritter (Vicar) on Jul 21, 2014 at 10:38 UTC

    Is it intentional that the last one's only got three parts to it? Anyhow, here's one regex that'll work:

    /^(?:[\dx]{1,3}\.){0,3}[\dx]{1,3}$/

    This will match between 1 and 4 blocks, each consisting of 1 to 3 digits or x's, separated by periods.

    Are you dealing with IP addresses there? If so, you may also be interested in Net::IP::Match, Net::IP::Match::* and Net::IP::CMatch.

    EDIT: the OP both edited his post and changed the examples of strings he'd like to match after I posted the above. For reference, this was the original post, in its entirety:

    I am trying to have a Regex for a dotted number format as shown below

    • 8.1xx.x.x
    • 9.0.3xx.x
    • 9.0.4xx.x
    • . . .
    • 9.1xx.x

    So any thoughts how I can make a generic regex for matching all these patterns.

      Basically these are version number for a product. So the series can be as given below

      • 8.1.1
      • 8.100.1
      • 9.0.300.1
      • 9.0.301.1
      • 9.0.400.1
      • 9.0.401.1
      • 9.1.0.0
      • 9.100.1.0

      So I need to make sure that if the version matches above then I need to skip running a particular script else run it.

        Please don't make substantial changes to your original posts in a way that makes answers you already received not make sense anymore. Instead, add an addendum to your post to clarify.

        Now, that said, what exactly is it you want to do now? You've got a list of version numbers and a version you want to match against them, and you want to run a particular script unless that version is on your list. So why not simply do exactly that in Perl?

        foreach (@versions) { unless($_ eq $version) { runscript(...); } }

        Or, more idiomatically:

        runscript(...) foreach (grep { $_ ne $version } @versions);
Re: Regex for matching dotted numbers
by SimonPratt (Friar) on Jul 21, 2014 at 11:59 UTC
    /^([1-9]\d+|[0-7])(\.\d{1,3}){0,3}$/

    Assumptions:

    • Version numbers greater than 0 (or 0.something) do not start with 0
    • Digit groups are no more than 3 digits long
    • Version numbers don't end with a period (.)

Re: Regex for matching dotted numbers
by jellisii2 (Hermit) on Jul 21, 2014 at 11:56 UTC
    This doesn't necessarily have to be done on a regex...
    my @ver = split /\./, $verstring;
    And test for whatever you wish there.

      I have done on similar line as the pattern was not consistent as I was thinking.

        Your supplied test data doesn't suggest this. If it's not 3 or 4 numbers separated by a dot, what is it? If it is separated by a dot, you can check scalar(@ver) to see if it's 3 or 4 numbers, and check $ver[0] to get your major number, and continue from there. You could even use one of the many switch analogs from CPAN to implement switch statements on the version numbers.
Re: Regex for matching dotted numbers
by QM (Parson) on Jul 21, 2014 at 10:42 UTC
    It helps if you show what you've already tried, and how it behaves. Also tell us what your criteria are, so we can judge which solutions work for you.

    Given that I'm lazy today, I'll give a short answer anyway (untested):

    my @nums = $dotted_num_string =~ /^(\d+)(?:\.(\d+))*$/;

    ...which captures the numeric parts in @nums.

    If you have some known restriction on how many or how few numeric fields there are, you can use a quantifier:

    my @nums = $dotted_num_string =~ /^(\d+)(\.\d+){3,5}$/;

    gives 4 to 6 numeric fields.

    -QM
    --
    Quantum Mechanics: The dreams stuff is made of

      my @nums = $dotted_num_string =~ /^(\d+)(?:\.(\d+))*$/;

      ...which captures the numeric parts in @nums.

      The second capture group above will only return the last substring matched even though it may match many times. A regex solution is possible, but just using split might be preferable. (It's also important to know if the dotted number string is 'alone' or is embedded in a longer string, whether recognition or extraction is intended, etc., none of which is entirely clear to me.)

      c:\@Work\Perl\monks>perl -wMstrict -le "my $dotted_num_string = '1.22.333.4444'; my @nums = $dotted_num_string =~ /^(\d+)(?:\.(\d+))*$/; printf qq{'$_' } for @nums; print ''; ;; @nums = $dotted_num_string =~ /^(\d+)(\.\d+){3,5}$/; printf qq{'$_' } for @nums; print ''; ;; @nums = $dotted_num_string =~ m{ \G [.]? (\d+) }xmsg; printf qq{'$_' } for @nums; " '1' '4444' '1' '.4444' '1' '22' '333' '4444'
        Yes, agreed. This seems to be a simpler version of your last one:
        @nums = $dotted_num_string =~ /(?:(\d+)\.?)/g;

        but allows a final trailing dot.

        I think your idea of using split, with suitable tests, is probably the best generic solution, barring any further constraints.

        -QM
        --
        Quantum Mechanics: The dreams stuff is made of

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others imbibing at the Monastery: (4)
As of 2024-04-23 16:00 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found