By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
437,695 Members | 1,956 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 437,695 IT Pros & Developers. It's quick & easy.

Regular expression in Perl

P: 5
I have a regex which extratcs the name from it.

The code is given below:
Expand|Select|Wrap|Line Numbers
  1. # Extract some parts from regex
  2. $input = "Hello, Shane !";
  3. $pattern = "^Hello, \\w+\\s*!\$";
  4.  
  5. if($input =~ /$pattern/) {
  6.     print "\nThe input matches the pattern The dollar variables are\n";  
  7.     print " \nONE == $1";
  8.     print "\n";
  9. }
  10.  
  11. The input matches the pattern The dollar variables are  
  12. ONE == Shane 
Now, if I want to extract the name, like this :

Problem:
Now, I'd like to match the earlier, and get the extracted data ("Shane" here in our example) by a designated name, not a number set by the regex.

Eg.:

^Hello, (?{surname}\w+)\s*!$

then I'll have a way to get the extracted data into $surname or maybe there is a way to do something like this:
Expand|Select|Wrap|Line Numbers
  1. my $input = "Hello, Shane !";
  2. my $regex = '^Hello, (?{surname}\w+)\s*!$'
  3. my %match = Regex.match($regex, $input);
  4. $match{"surname"} == "Shane"; # true
Regex.match() is the sub routine name given by me(dont confuse with any existing in built module in Perl).
It is this sub routine which has the functionality of matching the regex and returning the extracted data in the parameter surname.


Any help is highly appreciated.

Thanks.

Regards,
Sakshi
May 27 '10 #1

✓ answered by toolic

Update: As Sakshismriti discovered, named regex captures are now possible as of Perl version 5.10.0.


Original reply:
I think you must use the special number variables, but that's not a bad thing:

Expand|Select|Wrap|Line Numbers
  1. use strict;
  2. use warnings;
  3. use Data::Dumper;
  4.  
  5. my $input   = 'Hello, Shane !';
  6. my $pattern = qr{^Hello, (\w+)\s*!$};
  7. my %match;
  8. if ($input =~ /$pattern/) {
  9.     $match{surname} = $1;
  10. }
  11.  
  12. print Dumper(\%match);
  13.  
  14. __END__
  15.  
  16. $VAR1 = {
  17.           'surname' => 'Shane'
  18.         };
  19.  

Share this Question
Share on Google+
3 Replies


Expert
P: 70
Update: As Sakshismriti discovered, named regex captures are now possible as of Perl version 5.10.0.


Original reply:
I think you must use the special number variables, but that's not a bad thing:

Expand|Select|Wrap|Line Numbers
  1. use strict;
  2. use warnings;
  3. use Data::Dumper;
  4.  
  5. my $input   = 'Hello, Shane !';
  6. my $pattern = qr{^Hello, (\w+)\s*!$};
  7. my %match;
  8. if ($input =~ /$pattern/) {
  9.     $match{surname} = $1;
  10. }
  11.  
  12. print Dumper(\%match);
  13.  
  14. __END__
  15.  
  16. $VAR1 = {
  17.           'surname' => 'Shane'
  18.         };
  19.  
May 27 '10 #2

P: 5
Thanks for the help.
I have also made another solution for me and it is working fine :

Expand|Select|Wrap|Line Numbers
  1. #!/opt/perl/bin/perl
  2.  
  3. # Test regex with surname 
  4. my $input_string = "Hello, Shane !";
  5. my $regex_string = "^Hello, (?{surname}\\w+)\\s*!\$";
  6.  
  7. my  %match = match($regex_string, $input_string);
  8. if ($match{"code"} != 0) { 
  9.     print $match{"error_msg"};
  10. } else {
  11.     print "\nExtracted string is: [". $match{"surname"}. "]\n";
  12. }
  13.  
  14. # Test regex with another word called color in place of surname    
  15. # I made another input string and regex for it 
  16. $input_string = "The, red cherries !";
  17. $regex_string = "^The, (?{color}\\w+)\\s*\\w+\\s*!\$";
  18.  
  19. %match =  match($regex_string, $input_string);
  20. if ($match{"code"} != 0) { 
  21.     print $match{"error_msg"};
  22. } else {
  23.     print "\nExtracted string is: [". $match{"color"}. "]\n";
  24. }
  25.  
  26. # Test above regex non matching pattern      
  27. # I made another input string and regex for it 
  28. $input_string = "The red cherries !";
  29. $regex_string = "^The, (?{color}\\w+)\\s*\\w+\\s*!\$";
  30.  
  31. %match =  match($regex_string, $input_string);
  32. if ($match{"code"} != 0) { 
  33.     print $match{"error_msg"};
  34. } else {
  35.     print "\nExtracted string is: [". $match{"color"}. "]\n";
  36. }
  37.  
  38. sub match () {
  39.     my $regex = shift();
  40.     my $input = shift();
  41.  
  42.     my %return = ();
  43.     my $param_name;
  44.     # Extract the name of return type from regex
  45.     if($regex =~ s/\?{(.+)}//) { 
  46.         $param_name = $1; 
  47.  
  48.     } else {
  49.         $return{"code"} = 1;
  50.         $return{"error_msg"} = "Improper regex [$regex] given as input.";
  51.         return %return;
  52.     }
  53.  
  54.     # Compare input with the regex
  55.     if($input =~ /$regex/) {
  56.         $return{"code"} = 0;
  57.         $return{$param_name} = $1;
  58.         return %return;
  59.     } else {
  60.         $return{"code"} = 1;
  61.         $return{error_msg} = "There are no match corresponding to your search.";
  62.         return %return;
  63.     }
  64. }
  65.  
  66.  
Regards,
Sakshi
May 28 '10 #3

P: 5
@sakshismriti
Hey,

I got the more appropriate solution, I have to use labelled capturing groups in perl which is new in Perl 5.0
Read it here :
http://books.google.com/books?id=lNV...page&q&f=false

The solution is as follows:
Expand|Select|Wrap|Line Numbers
  1. #!/usr/bin/perl -w
  2. use strict;
  3. use Data::Dumper; # for debug only
  4.  
  5. my $input = 'Hello, Shane !';
  6. my $regex = qr/^Hello, (?<surname>\w+)\s*!$/;
  7. my %match = match($regex, $input);
  8. # print("\nthis is match" . Dumper(%match));
  9. print ("\n The matched value ios === ". $match{"surname"});    
  10. # $match{surname} eq 'Shane'; # true
  11.  
  12.  
  13. sub match {
  14.    $_[1] =~ $_[0];
  15.    map { $_ => $+{$_} } keys %+;
  16. }
  17.  
Cheers!!!
Sakshi
May 28 '10 #4

Post your reply

Sign in to post your reply or Sign up for a free account.