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

What is the quickest way to extract a value out of a string if I know the text pattern before and after the value?

For example if I want to extract the password value 'foo' from the string 'password=foo&user=bar', then I will look between the text 'password=' and the ampersand.

I know how to do that with a few statements using split() but is there a one-line regex that will do it?

Replies are listed 'Best First'.
Re: simple regex question
by Your Mother (Archbishop) on Jul 16, 2005 at 21:45 UTC

    If you're really parsing query strings and you don't have some bizarre format requirement for it, you shouldn't do it that way. It's harder than it looks from the start and there are many gotchas. A few modules do query string parsing for you, including CGI, but my favorite lately is URI::QueryParam.

    use URI; use URI::QueryParam; # extends functionality of URI my $uri = URI->new('https://what.who/form.pl?password=foo&user=bar'); print $uri->query_param('password'), $/;
Re: simple regex question
by holli (Abbot) on Jul 16, 2005 at 18:01 UTC
    $_ = 'password=foo&user=bar'; print $1 if /password=(.+?)&/;


    holli, /regexed monk/
      This is nothing to do with the original question as such. Just curious. To print 'foo' we can just use this right?  perl -le '$_ = "password=foo&user=bar"; print /password=(.+?)&/;'

      output: foo

      by the same token, am i correct in assuming if we were setting $1, $2 etc.  /regexstuff/ will return $1 . $2?

      thanks

      SK

        am i correct in assuming if we were setting $1, $2 etc. /regexstuff/ will return $1 . $2?

        No, but why guess? Here's the relevant section of perlop:

        m/PATTERN/cgimosx
        /PATTERN/cgimosx

        Searches a string for a pattern match, and in scalar context returns true if it succeeds, false if it fails.

        ...

        If the "/g" option is not used, "m//" in list con­text returns a list consisting of the subexpres­sions matched by the parentheses in the pattern, i.e., ($1, $2, $3...). ... When there are no parentheses in the pattern, the return value is the list "(1)" for success. With or without parentheses, an empty list is returned upon failure.

        the lowliest monk

Re: simple regex question
by redss (Monk) on Jul 16, 2005 at 18:52 UTC
    I figured out the problem, I needed to use parenthesis around the lvalue

    i.e. ($value) = $string =~ /password=(.+?)&/;

    thanks!