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

Greetings monks,

I was using Perl 5.8, and recently switched to perl 5.12 ( which comes default on suse 11.3). While browsing for regular expressions, i got some issues while converting regular expression from 5.8 to equivalent in 5.10, below is my working code.

use strict; use Data::Dumper; my %hash=(); my $str="Test Tester Testing [Feb 18: 28_10_10] Test"; #my $reg='(?<fname>\w+\b)\s(?<mname>\w+)\s(?<lname>\w+\s).*\]\k<fname> +'; #my $reg='(\w+)\s(\w+)\s(\w+).*?\[(.*?)\]$1'; my $reg='(\w+) (\w+) (\w+) \[([\w\W]+)\] (.*?)'; { # use re 'debug'; if($str =~ /$reg/is) { # %hash=%+; $hash{fname}=$1; $hash{mname}=$2; $hash{lname}=$3; $hash{date}=$4; # %hash=%+; } } print Dumper \%hash;

I am trying
#my $reg='(?<fname>\w+\b)\s(?<mname>\w+)\s(?<lname>\w+\s).*\]\k<fname>';

in 5.10, and that seems to be not working :( ...
Can anybody point me what i am doing wrong... !!!

Thanks,
Shekar

Replies are listed 'Best First'.
Re: Help required on understanding regular expressions
by Marshall (Canon) on Feb 20, 2012 at 07:46 UTC
    I don't see why you need to change anything.
    Regex in Perl 5.10 is a superset of 5.8.
    I modified your code slightly but it will run under both versions.
    I think should also run under Perl 5.6.
    I see no need here for fancy new features past what has been done for more than a decade.
    There are new things that can be done.
    But you may not have understood what could have been done in your prior code.

    use strict; use Data::Dumper; my %hash=(); my $str="Test Tester Testing [Feb 18: 28_10_10] Test"; my $reg='(\w+) (\w+) (\w+) \[([\w\W]+)\] (.*?)'; my ($fname, $mname, $lname, $date) = $str =~ /$reg/is; if (defined ($date)) { $hash{fname}=$fname; $hash{mname}=$mname; $hash{lname}=$lname; $hash{date} =$date; } print Dumper \%hash; __END__ $VAR1 = { 'date' => 'Feb 18: 28_10_10', 'lname' => 'Testing', 'mname' => 'Tester', 'fname' => 'Test' };
    Update:
    If you must, although without spacing the regex out onto multiple lines, it is harder to understand...

    use strict; use Data::Dumper; my %hash; my $str="Test Tester Testing [Feb 18: 28_10_10] TestXXX"; my $reg='(?<fname>\w+) (?<mname>\w+) (?<lname>\w+) \[(?<date>[\w\W]+)\ +]'; if ($str =~ /$reg/i) { %hash = %+; } print Dumper \%hash; __END__ $VAR1 = { 'lname' => 'Testing', 'date' => 'Feb 18: 28_10_10', 'fname' => 'Test', 'mname' => 'Tester' };
Re: Help required on understanding regular expressions
by ikegami (Patriarch) on Feb 20, 2012 at 09:16 UTC

    A regex pattern that worked in 5.8 will also work in 5.10. What did you have in 5.8?

    '^(\S+)\s+(\S+)\s+(\S+)\s+\[([^\]]*)\]\s+\1\z'

    Well, that will continue to work in 5.10. If you wanted to use named captures,

    '^(?<fname>\S+)\s+(?<mname>\S+)\s+(?<lname>\S+)\s+\[(?<date>[^\]]*)\]\ +s+\k<fname>\z'

    PS — Make sure to test your code with the following string:

    "Test Tester Testing [Feb 18: 28_10_10] Tests"

    It shouldn't match ("Test" ne "Tests"), but it's easy to match it if the pattern isn't properly anchored.

      Thanks monks for the reply.

      I am not converting anything, just wanted to learn new feature, Still not able to get it working ... below is the code.

      use strict; use Data::Dumper; my %hash=(); my $str="Test Tester Testing [Feb 18: 28_10_10] Test"; #my $reg='(?<fname>\w+\b)\s(?<mname>\w+)\s(?<lname>\w+\s).*\[(?<date>[ +^\]]+)/'; my $reg='^(?<fname>\S+)\s+(?<mname>\S+)\s+(?<lname>\S+)\s+\[(?<date>[^ +\]]*)\]\+s+\k<fname>\z'; { if($str =~ /$reg/) { %hash=%+; } } print Dumper \%hash;

      Thanks.
        Still not able to get it working
        As in, you get compile errors? Run time errors? Unexpected results? Or does the program sit on the couch, demanding beer and crips?

        Be specific, don't expect us to download your code and run it, just to find out what your "does not work" means. Tell us what you mean by "not working", and show us the errors and output you are getting.

        You got typos :) this means start using /x so you can see them clearly

        my $reg = qr/ ^ (?<fname>\S+) \s+ (?<mname>\S+) \s+ (?<lname>\S+) \s+ \[ (?<date>[^\]]*) \] \+s+ # TYPOS \k<fname> \z /x;
Re: Help required on understanding regular expressions
by NetWallah (Canon) on Feb 20, 2012 at 07:49 UTC
    The "]" was facing the wrong way, and I don't know why you used the "\k". This one works:
    /(?<fname>\w+\b)\s(?<mname>\w+)\s(?<lname>\w+\s).*\[(?<date>[^\]]+)/

                “PHP is a minor evil perpetrated and created by incompetent amateurs, whereas Perl is a great and insidious evil perpetrated by skilled but perverted professionals.”
            ― Jon Ribbens

      I dont understand the code.. /(?<fname>\w+\b)\s(?<mname>\w+)\s(?<lname>\w+\s).*\[(?<date>[^\]]+)/ what it is looking for from string?
        /(?<fname>\w+\b) # Looks for "\w" (Word characters followed by a word +boundary (look up \w and \b) # and creates $+{name} \s(?<mname>\w+)\s # Same thing - Whitespace on both sides (?<lname>\w+\s) # Same thing .*\[(?<date>[^\]]+)/ # looks for "[", followed by anything that is NOT + "]", and populates $+{date}
        All this is in the "perlre" document.

                    “PHP is a minor evil perpetrated and created by incompetent amateurs, whereas Perl is a great and insidious evil perpetrated by skilled but perverted professionals.”
                ― Jon Ribbens

Re: Help required on understanding regular expressions
by Anonymous Monk on Feb 20, 2012 at 07:49 UTC

    i got some issues while converting regular expression from 5.8 to equivalent in 5.10

    There is no need to convert :D

      Well, Thanks for pointing out... it was miss phrased.