Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation

Replacing parts of a string

by spiderbo (Sexton)
on Apr 11, 2003 at 13:55 UTC ( #249886=perlquestion: print w/replies, xml ) Need Help??
spiderbo has asked for the wisdom of the Perl Monks concerning the following question:


I have a string, +e=TUTOR&CalendarName=102138Academic&framename=top.index_main&session_ +number=618280744437303

I would like to replace three parts of the string, the first two should be feasible, I would like to replace '&month=04' and '&year=2003'(where 04 can be any two digits and 2003 can be any four digits) with ''.

However, my third replace is a little more complicated. I would like to replace '&CalendarName=102138Academic' with ''. The poblem is the length of the value of CalendarName (in this case 102138Academic) will vary.

The remaining parameters in the string I would like to leave as they are. The order of the parameters in the string may also vary.

Is the above possible?

Any advice apreciated!

Replies are listed 'Best First'.
Re: Replacing parts of a string
by tachyon (Chancellor) on Apr 11, 2003 at 14:51 UTC

    Use to do it for you thusly (this is very robust):

    $str = " +user_type=TUTOR&CalendarName=102138Academic&framename=top.index_main& +session_number=618280744437303"; # first amputate the bit $str =~ s/^[^\?]+\?//; # use to parse the string by creating a CGI instance from it use CGI; $q = CGI->new($str); # modify whatever you want, lets delete what you specified $q->delete('CalendarName'); $q->delete('month'); $q->delete('year'); # and modify loginid just for laughs $q->param( 'loginid', 'haxor' ); # add a new param if you want $q->param('i am a new one', 'this is my value' ); # write out the new query string (default is to use ; not & so we do:) $CGI::USE_PARAM_SEMICOLONS = 0; print $q->query_string(); __DATA__ loginid=haxor&student_id=&user_type=TUTOR&framename=top.index_main&ses +sion_number=618280744437303&i%20am%20a%20new%20one=this%20is%20my%20v +alue

    You will be hard pressed to break this solution - it is much better than using regexes from a robustness point of view.




      You're Good! That looks a smart plan indeed. Will give it a go.

      silly question, however I know it will take you seconds to answer and me hours to find, but, how do you get the bit which you strippped when you did:

      $str =~ s/^[^\?]+\?//;

      i.e. I am looking for ''

      Thank you.

        You can capture into $1, $2, $etc using parens around (what you want) in a regex. If there are multiple parens then you get the first capture in $1, next in $2, etc

        $str = ''; # the typical perlish idiom looks like this # we are capturing $1 and $2 and assigning them to vars # all in one line (note this uses m//) my ( $site, $q_string ) = $str =~ m/^([^\?]+)\?(.*)$/; print "site: $site\nq string: $q_string\n"; # simple way, just modifying the s/// we had $str =~ s/^([^\?]+)\?//; my $capture = $1; print $capture; # $str now contains q string

        Details see perlre




Re: Replacing parts of a string
by krujos (Curate) on Apr 11, 2003 at 14:00 UTC
    If you always have numeric followed by alphabetic in that field how about:
    UPDATE: Fixed formatting

      Just a word - your regex is better written without capturing. s/(?<=CalendarName=)[^&=]*/ReplacementString/. In this case I used a positive assertion so it only begins matching as it hits the end of 'CalendarName=' at which point it replaces everything that isn't an ampersand or an equal character.

Re: Replacing parts of a string
by jasonk (Parson) on Apr 11, 2003 at 14:08 UTC

    You could do the regexp thing: $string =~ s/month=\d+/month=$newmonth/g;, or if the code you are working on is, and you already have a object you are working with, I find this is a really easy way to get slightly modified URLs:

    my $cgi = new CGI; # .... bunch of code here .... # need to get a url that takes us back to new years my $newyears = new CGI($cgi); $newyears->param('month',1); $newyears->param('day',1); my $newyears_url = $newyears->self_url;

    Generally I just abstract this into a little subroutine:

    sub new_self_url { my %params = @_; my $new = new CGI($cgi); foreach(keys %params) { $new->param($_,$params{$_}); } return $new->self_url; } # now you can get urls back to your script with different # dates like this: my $newyears = new_self_url(month => 1, day => 1); my $christmas = new_self_url(month => 12, day => 25);

    We're not surrounded, we're in a target-rich environment!

      Unfortunately the code is not, so I will try your

      $string =~ s/month=\d+/month=$newmonth/g;
      for my month and year.

      Still to find a solution for the CalendarName then... In response to your comment, it could be numeric or alphnumeric, in any order.

Re: Replacing parts of a string
by arturo (Vicar) on Apr 11, 2003 at 14:52 UTC

    OK, this will not enhance your regex-fu, and it may not be the most efficient (in terms of runtime resource allocation) solution, but it's a dead easy one to use, and very efficient in terms of programmer-hours spent on the problem. Following up on jasonk's suggestion, you don't even need it to be the case that the script doing the parsing is Simply feed the query string to a object and let it do the parsing for you:

    #!/usr/bin/perl + use CGI; use strict; use warnings; # note you want everything after the ? my $querystring='loginid=102138&month=04&year=2003&student_id=&user_ty +pe=TUTOR&CalendarName=102138Academic&framename=top.index_main&session +_number=618280744437303'; + my $q = CGI->new($querystring); + foreach my $p ( $q->param() ) { print "Parameter $p : " . $q->param($p) . "\n"; } +

    If not P, what? Q maybe?
    "Sidney Morgenbesser"

      ditto...use or similar--or be at the peril of code injection inside URLs. You should also use taint...and check (with a simple regex) that the parameters you receive are alphanumeric only (no quotes etc.) Chris
Re: Replacing parts of a string
by Tomte (Priest) on Apr 11, 2003 at 14:22 UTC

    Just to provide another way:

    my $string = " +t_id=&user_type=TUTOR&CalendarName=102138Academic&framename=top.index +_main&session_number=618280744437303"; my $i = index($string,"CalendarName=") + length("CalendarName="); my $j = index($string, "&", $i); substr($string,$i,$j-$i) = "";

    I don't recommend it, but I'm always astounded that this is possible, maybe one enlightened monk can come up with a suggestion where this lvalue-assignement (?!?) is useful.
    Update: in Re: Replace zero-width grouping?, BrowserUk comes up with a good use of an substr lvalue--assignement.


    Hlade's Law:

    If you have a difficult task, give it to a lazy person --
    they will find an easier way to do it.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://249886]
Front-paged by diotalevi
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others romping around the Monastery: (10)
As of 2017-01-23 15:22 GMT
Find Nodes?
    Voting Booth?
    Do you watch meteor showers?

    Results (192 votes). Check out past polls.