Beefy Boxes and Bandwidth Generously Provided by pair Networks
Pathologically Eclectic Rubbish Lister
 
PerlMonks  

Regexp help

by Anonymous Monk
on Sep 03, 2010 at 16:21 UTC ( [id://858739]=perlquestion: print w/replies, xml ) Need Help??

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

Hi Monks,

I am trying to get the servername from the string as below: string: "R4:abcxyz45:LNX" From this I am trying to extract "abcxyz45" using regular expression. Below is the code I am using but not getting any return value. What I am doing wrong? any idea.

$str = "R4:abcxyz45:LNX"; $str =~ /[\w\d]+(^:[\w\d]+:$)\w+/;
Thanks

Replies are listed 'Best First'.
Re: Regexp help
by kennethk (Abbot) on Sep 03, 2010 at 16:26 UTC
    You are not using the anchors ^ and $ correctly. As it says in perlretut:

    Sometimes, however, we'd like to specify where in the string the regexp should try to match. To do this, we would use the anchor metacharacters ^ and $ . The anchor ^ means match at the beginning of the string and the anchor $ means match at the end of the string, or before a newline at the end of the string.

    You also misplaced your parentheses assuming you do not wish to capture leading and trailing :. You will get your expected result with

    $str = "R4:abcxyz45:LNX"; $str =~ /^[\w\d]+:([\w\d]+):\w+$/;

    or

    $str = "R4:abcxyz45:LNX"; $str =~ /[\w\d]+:([\w\d]+):\w+/;

    or even

    $str = "R4:abcxyz45:LNX"; $str =~ /:([\w\d]+):/;
    depending on your needs.
      ... and simplifying even further to
      $str =~ /:([\w]+):/;

      Since \d is a subset of \w, [\w\d] is the same as [\w].

      Then the square brackets are also not needed:

      $str =~ /:(\w+):/;

      my bad ... really my bad.silly mistake :). I got it. Thanks a lot Kenneth. Happy Weekend.

Re: Regexp help
by toolic (Bishop) on Sep 03, 2010 at 16:43 UTC
    In addition to kennethk's help, in the future, you could use YAPE::Regex::Explain to help debug a regex:
    use YAPE::Regex::Explain; my $re = '[\w\d]+(^:[\w\d]+:$)\w+'; print YAPE::Regex::Explain->new($re)->explain(); __END__ The regular expression: (?-imsx:[\w\d]+(^:[\w\d]+:$)\w+) matches as follows: NODE EXPLANATION ---------------------------------------------------------------------- (?-imsx: group, but do not capture (case-sensitive) (with ^ and $ matching normally) (with . not matching \n) (matching whitespace and # normally): ---------------------------------------------------------------------- [\w\d]+ any character of: word characters (a-z, A- Z, 0-9, _), digits (0-9) (1 or more times (matching the most amount possible)) ---------------------------------------------------------------------- ( group and capture to \1: ---------------------------------------------------------------------- ^ the beginning of the string ---------------------------------------------------------------------- : ':' ---------------------------------------------------------------------- [\w\d]+ any character of: word characters (a-z, A-Z, 0-9, _), digits (0-9) (1 or more times (matching the most amount possible)) ---------------------------------------------------------------------- : ':' ---------------------------------------------------------------------- $ before an optional \n, and the end of the string ---------------------------------------------------------------------- ) end of \1 ---------------------------------------------------------------------- \w+ word characters (a-z, A-Z, 0-9, _) (1 or more times (matching the most amount possible)) ---------------------------------------------------------------------- ) end of grouping ----------------------------------------------------------------------

    Also note that, since \d is a subset of \w, [\w\d] is the same as (and more simply coded as) [\w].

Re: Regexp help
by talexb (Chancellor) on Sep 03, 2010 at 17:31 UTC

    A regular expression isn't necessary. How about just using split with a ':' delimiter, then taking the second array element of the result?

    main::(-e:1): 1 DB<1> $str = "R4:abcxyz45:LNX" DB<2> @words = split(':',$str) DB<3> x $words[1] 0 'abcxyz45'

    Alex / talexb / Toronto

    "Groklaw is the open-source mentality applied to legal research" ~ Linus Torvalds

      To just get one item, use list slice.

      A very handy technique. Note that the order of the vars on the left don't have to be in the same order that they are in the input string (the indicies to the slice can be in any order).

      I usually order the vars on the left to be in the order that they will be used in the code that follows the split. I fiddle with the indices on the right to make that possible. Also here I used a -1 instead of 2 just to show that is possible (-1 means the last thing in list)

      Oh, PS, yes it is possible to write a single char like ':' to use in the split instead of /:/, but I always use the regex form.

      #!/usr/bin/perl -w use strict; my $x = 'R4:abcxyz45:LNX'; my $server = (split(/:/,$x))[1]; print "$server\n"; #prints abcxyz45 (my $OS, $server) = (split(/:/,$x))[-1,1]; print "$OS $server\n"; #prints LNX abcxyz45

      A regular expression is necessary because the first argument to split is a regular expression.

Re: Regexp help
by dasgar (Priest) on Sep 03, 2010 at 16:52 UTC

    If you wanted to shorten up the regex, you could do something like this:

    my $str = "R4:abcxyz45:LNX"; my ($servername) = ($str =~ /:(.+):/);

    However, I should point out that this has a greater potential to create problems than the regexes offered by kennethk. In other words, the above has shorter keystrokes, but kennethk's solutions are safer.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others taking refuge in the Monastery: (5)
As of 2024-04-16 16:58 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found