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

Hello, I need to match a string like this: "one.two.three". Each title is separated by a ".", and there must be at least one title, but the others are optional. Here is my attempt:
while ("one.two.three" =~ /([A-Za-z0-9_].+)\.?([A-Za-z0-9_].+)?/g) { print "$1\n"; }
Thank you for any help you can give.

Replies are listed 'Best First'.
Re: Match Optional Groups with 1 Required Group
by BrowserUk (Patriarch) on Feb 04, 2014 at 00:25 UTC
    print "$_: ", m[^\w+(?:\.\w+){0,2}$] ? 'matched' : 'failed' for qw[ one one.two one.two.three one. one-two ];; one: matched one.two: matched one.two.three: matched one.: failed one-two: failed

    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
      Each title needs at least one character as well.
        Ah sweet.
      This is great. I should have put in the post that there can be an unlimited number of titles, as long as there is one. I'm trying to modify it to allow that:
      print "$_: ", m[^\w+(?:\.\w+)?$] ? "matched\n" : "failed\n" for qw[ one one.two one.two.three four.five.six.seven one. one-two + ];

        ? is zero or one. You need *, which is 0 or more.:

        print "$_: ", m[^\w+(?:\.\w+)*$] ? "matched\n" : "failed\n" for qw[ one one.two one.two.three four.five.six.seven one. one-tw +o ];; one: matched one.two: matched one.two.three: matched four.five.six.seven: matched one.: failed one-two: failed
        Each title needs at least one character as well.

        + means 1 or more, so that's covered by \w+


        With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.
Re: Match Optional Groups with 1 Required Group
by kcott (Archbishop) on Feb 04, 2014 at 05:51 UTC

    G'day rem45acp,

    Here's another way to do it (I've added a few more tests to ones you posted):

    #!/usr/bin/env perl -l use strict; use warnings; my @tests = qw{ one one.two one.two.three four.five.six.seven one. one-two .one .one. . .. .@. one.good.egg one.-bad-.egg }; print "'$_': ", grep(! /^\w+$/, split /\./, $_, -1) ? 'bad' : 'good' f +or @tests;

    Output:

    'one': good 'one.two': good 'one.two.three': good 'four.five.six.seven': good 'one.': bad 'one-two': bad '.one': bad '.one.': bad '.': bad '..': bad '.@.': bad 'one.good.egg': good 'one.-bad-.egg': bad

    [See split if you're unfamiliar with the 3-argument form.]

    -- Ken

Re: Match Optional Groups with 1 Required Group
by rem45acp (Novice) on Feb 04, 2014 at 00:22 UTC
    I just realized I could probably use split and then validate each one. However, I'm still open to a regex solution.
      Using the split function is exactly what I was going to suggest after having read your original post since it is particularly appropriate for text chunks delimited by separators (although a capturing regex can of course also do it, as shown in the posts below). As a side note, have a look at predefined character classes, such as \w, which can save you quite a bit of typing and make your regexes easier to read and understand.